程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c# Invoke和BeginInvoke 差別剖析

c# Invoke和BeginInvoke 差別剖析

編輯:C#入門知識

c# Invoke和BeginInvoke 差別剖析。本站提示廣大學習愛好者:(c# Invoke和BeginInvoke 差別剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是c# Invoke和BeginInvoke 差別剖析正文


Control.Invoke 辦法 (Delegate) :在具有此控件的基本窗口句柄的線程上履行指定的拜托。

Control.BeginInvoke 辦法 (Delegate) :在創立控件的基本句柄地點線程上異步履行指定拜托。

(一)Control的Invoke和BeginInvoke

我們要基於以下熟悉:
(1)Control的Invoke和BeginInvoke與Delegate的Invoke和BeginInvoke是分歧的。
(2)Control的Invoke和BeginInvoke的參數為delegate,拜托的辦法是在Control的線程上履行的,也就是我們日常平凡所說的UI線程。

我們以代碼(一)來看(Control的Invoke)

private delegate void InvokeDelegate();
private void InvokeMethod(){
//C代碼段
}
private void butInvoke_Click(object sender, EventArgs e) {
//A代碼段.......
this.Invoke(new InvokeDelegate(InvokeMethod));
//B代碼段......
}

你認為代碼的履行次序是甚麼呢?記好Control的Invoke和BeginInvoke都履行在主線程即UI線程上
A------>C---------------->B
說明:(1)A在UI線程上履行完後,開端Invoke,Invoke是同步
(2)代碼段B其實不履行,而是立刻在UI線程上履行InvokeMethod辦法,即代碼段C。
(3)InvokeMethod辦法履行完後,代碼段C才在UI線程上持續履行。

看看代碼(二),Control的BeginInvoke

private delegate void BeginInvokeDelegate();
private void BeginInvokeMethod(){
//C代碼段
}
private void butBeginInvoke_Click(object sender, EventArgs e) {
//A代碼段.......
this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod));
//B代碼段......
}

你認為代碼的履行次序是甚麼呢?記好Control的Invoke和BeginInvoke都履行在主線程即UI線程上
A----------->B--------------->C鄭重,這個只做參考。。。。。,我也不願定履行次序,假如有哪位達人曉得的話請告訴。

說明::(1)A在UI線程上履行完後,開端BeginInvoke,BeginInvoke是異步

(2)InvokeMethod辦法,即代碼段C不會履行,而是立刻在UI線程上履行代碼段B。
(3)代碼段B履行完後(就是說butBeginInvoke_Click辦法履行完後),InvokeMethod辦法,即代碼段C才在UI線程上持續履行。

由此,我們曉得:

Control的Invoke和BeginInvoke的拜托辦法是在主線程,即UI線程上履行的。也就是說假如你的拜托辦法用來取消費時光長的數據,然後更新界面甚麼的,萬萬別在UI線程上挪用Control.Invoke和Control.BeginInvoke,由於這些是仍然壅塞UI線程的,形成界面的假逝世。

那末,這個異步究竟是甚麼意思呢?

異步是指絕對於挪用BeginInvoke的線程異步,而不是絕對於UI線程異步,你在UI線程上挪用BeginInvoke ,固然不可了。----摘自"Invoke和BeginInvoke的真正涵義"一文中的評論。
BeginInvoke的道理是將挪用的辦法Marshal成新聞,然後挪用Win32 API中的RegisterWindowMessage()向UI窗口發送新聞。----摘自"Invoke和BeginInvoke的真正涵義"一文中的評論。

(二)我們用Thread來挪用BeginInvoke和Invoke

我們開一個線程,讓線程履行一些消耗時光的操作,然後再用Control.Invoke和Control.BeginInvoke回到用戶UI線程,履行界面更新。

代碼(三) Thread挪用Control的Invoke

private Thread invokeThread;
private delegate void invokeDelegate();
private void StartMethod(){
//C代碼段......
Control.Invoke(new invokeDelegate(invokeMethod));
//D代碼段......
}
private void invokeMethod(){
//E代碼段
}
private void butInvoke_Click(object sender, EventArgs e) {
//A代碼段.......
invokeThread = new Thread(new ThreadStart(StartMethod));
invokeThread.Start();
//B代碼段......
}


你認為代碼的履行次序是甚麼呢?記好Control的Invoke和BeginInvoke都履行在主線程即UI線程上
A------>(Start一開端B和StartMethod的C就同時履行)---->(C履行完了,不論B有無履行完,invokeThread把新聞封送(invoke)給UI線程,然後本身期待)---->UI線程處置完butInvoke_Click新聞後,處置invokeThread封送過去的新聞,履行invokeMethod辦法,即代碼段E,處置往後UI線程切換到invokeThread線程。

這個Control.Invoke是絕對於invokeThread線程同步的,阻攔了其運轉。


說明:

1。UI履行A
2。UI開線程InvokeThread,B和C同時履行,B履行在線程UI上,C履行在線程invokeThread上。
3。invokeThread封送新聞給UI,然後本身期待,UI處置完新聞後,處置invokeThread封送的新聞,即代碼段E
4。UI履行完E後,轉到線程invokeThread上,invokeThread線程履行代碼段D

代碼(四) Thread挪用Control的BeginInvoke

private Thread beginInvokeThread;
private delegate void beginInvokeDelegate();
private void StartMethod(){
//C代碼段......
Control.BeginInvoke(new beginInvokeDelegate(beginInvokeMethod));
//D代碼段......
}
private void beginInvokeMethod(){
//E代碼段
}
private void butBeginInvoke_Click(object sender, EventArgs e) {
//A代碼段.......
beginInvokeThread = new Thread(new ThreadStart(StartMethod));
beginInvokeThread .Start();
//B代碼段......
}


你認為代碼的履行次序是甚麼呢?記好Control的Invoke和BeginInvoke都履行在主線程即UI線程上
A在UI線程上履行----->beginInvokeThread線程開端履行,UI持續履行代碼段B,並發地invokeThread履行代碼段C-------------->不論UI有無履行完代碼段B,這時候beginInvokeThread線程把新聞封送給UI,單本身其實不期待,持續向下履行-------->UI處置完butBeginInvoke_Click新聞後,處置beginInvokeThread線程封送過去的新聞。



說明:

1。UI履行A
2。UI開線程beginInvokeThread,B和C同時履行,B履行在線程UI上,C履行在線程beginInvokeThread上。
3。beginInvokeThread封送新聞給UI,然後本身持續履行代碼D,UI處置完新聞後,處置invokeThread封送的新聞,即代碼段E
有點疑問:假如UI先履行終了,是否是有能夠過了段時光beginInvokeThread才把新聞封送給UI,然後UI才持續履行封送的新聞E。如圖淺綠的部門。

Control的BeginInvoke是絕對於挪用它的線程,即beginInvokeThread絕對是異步的。
是以,我們可以想到。假如要異步取消耗長時光的數據,好比從數據庫中讀年夜量數據,我們應當這麼做。
(1)假如你想阻攔挪用線程,那末挪用代碼(三),代碼段D刪失落,C改成消耗長時光的操作,由於這個操作是在別的一個線程中做的。代碼段E改成更新界面的辦法。
(2)假如你不想阻攔挪用線程,那末挪用代碼(四),代碼段D刪失落,C改成消耗長時光的操作,由於這個操作是在別的一個線程中做的。代碼段E改成更新界面的辦法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved