1. 程式人生 > >Invoke 和 BeginInvoke 的真正涵義

Invoke 和 BeginInvoke 的真正涵義

BeginInvoke 方法真的是新開一個執行緒進行非同步呼叫嗎?

參考以下程式碼:

publicdelegatevoid treeinvoke();
privatevoid UpdateTreeView()
{
    MessageBox.Show(System.Threading.Thread.CurrentThread.Name);
}
privatevoid button1_Click(object sender, System.EventArgs e)
{
    System.Threading.Thread.CurrentThread.Name ="UIThread
"; treeView1.BeginInvoke(new treeinvoke(UpdateTreeView)); }

看看執行結果,彈出的對話方塊中顯示的是 UIThread,這說明 BeginInvoke 所呼叫的委託根本就是在 UI 執行緒中執行的。

既然是在 UI 執行緒中執行,又何來“非同步執行”一說呢?

我們再看看下面的程式碼:

publicdelegatevoid treeinvoke();
privatevoid UpdateTreeView()
{
    MessageBox.Show(Thread.CurrentThread.Name);
}
privatevoid button1_Click(object sender, System.EventArgs e) { Thread.CurrentThread.Name ="UIThread"; Thread th =new Thread(new ThreadStart(StartThread)); th.Start(); } privatevoid StartThread() { Thread.CurrentThread.Name ="Work Thread"; treeView1.BeginInvoke(new treeinvoke(UpdateTreeView)); }

再看看執行結果,彈出的對話方塊中顯示的還是 UIThread,這說明什麼?這說明 BeginInvoke 方法所呼叫的委託無論如何都是在 UI 執行緒中執行的。

那 BeginInvoke 究竟有什麼用呢?

在多執行緒程式設計中,我們經常要在工作執行緒中去更新介面顯示,而在多執行緒中直接呼叫介面控制元件的方法是錯誤的做法,具體的原因可以在看完我的這篇之後看看這篇:在多執行緒中如何呼叫Winform,如果你是大牛的話就不要看我這篇了,直接看那篇吧,反正那篇文章我沒怎麼看懂。

Invoke 和 BeginInvoke 就是為了解決這個問題而出現的,使你在多執行緒中安全的更新介面顯示。

正確的做法是將工作執行緒中涉及更新介面的程式碼封裝為一個方法,通過 Invoke 或者 BeginInvoke 去呼叫,兩者的區別就是一個導致工作執行緒等待,而另外一個則不會。

而所謂的“一面響應操作,一面新增節點”永遠只能是相對的,使 UI 執行緒的負擔不至於太大而以,因為介面的正確更新始終要通過 UI 執行緒去做,我們要做的事情是在工作執行緒中包攬大部分的運算,而將對純粹的介面更新放到 UI 執行緒中去做,這樣也就達到了減輕 UI 執行緒負擔的目的了。

而在那段更新樹節點的程式碼中,其實唯一起作用的程式碼是:System.Threading.Thread.Sleep(100);,它使 UI 執行緒有了處理介面訊息的機會,其實 數碼幽靈 將問題複雜化了,只要以下的程式碼就可以很好的工作了。

privatevoid button1_Click_(object sender, System.EventArgs e)
{
    TreeNode tn;
    for(int i=0;i<100000;i++)
    {
        tn=new TreeNode (i.ToString());
        this.treeView1.Nodes[0].Nodes.Add(tn);
        if (i%100 == 0) Application.DoEvents();
    }
}

相關推薦

C#中Invoke BeginInvoke涵義區別

參考以下程式碼: public delegate void treeinvoke(); privatevoidUpdateTreeView() {          MessageBox.Show(System.Threading.Thread.CurrentThread.Name); } privat

Invoke BeginInvoke真正涵義

BeginInvoke 方法真的是新開一個執行緒進行非同步呼叫嗎? 參考以下程式碼: publicdelegatevoid treeinvoke(); privatevoid UpdateTreeView() { MessageBox.Show(System.Threading.Thread

InvokeBeginInvoke真正含義

(一)Control的Invoke和BeginInvoke 我們要基於以下認識: (1)Control的Invoke和BeginInvoke與Delegate的Invoke和BeginInvoke是不同的。 (2)Control的Invoke和BeginInvoke的引數為

Invoke BeginInvoke 的區別

定義 調用 遊戲 click 控件 eight read 就是 並且 在Invoke或者BeginInvoke的使用中無一例外地使用了委托Delegate。 一、為什麽Control類提供了Invoke和BeginInvoke機制? 關於這個問題的最主要的原因已經是dot

控制元件的InvokeBeginInvoke

1.Control.Invoke Invoke 委託會導致執行緒的阻塞,但是是順序執行的, private void Form1_Load(object sender, EventArgs e) { listBox1.Items.Add("begin"); listBox1.I

invokebegininvoke 區別

一直對invoke和begininvoke的使用和概念比較混亂,這兩天看了些資料,對這兩個的用法和原理有了些新的認識和理解。 首先說下,invoke和begininvoke的使用有兩種情況: control中的invoke、begininvoke。 delegra

C# InvokeBeginInvoke(1)

 近日,被Control的Invoke和BeginInvoke搞的頭大,就查了些相關的資料,整理如下。感謝這篇文章對我的理解Invoke和BeginInvoke的真正含義 。 (一)Control的Invoke和BeginInvoke 我們要基於以下認識: (1)Control的

任運自在:執行緒(Thread)與委託(InvokeBeginInvoke封裝

執行緒(Thread)與委託(Invoke和BeginInvoke) 這幾天專門玩執行緒與委託,到處查詢資料看,漸漸明白了用法、寫法和一些注意事項; 描述: 什麼是程序呢?當一個程式開始執行時,它就是一個程序,程序所指包括執行中的程式和程式所使用到的記憶體和系統資源。而一個

c# InvokeBeginInvoke 區別

Control.Invoke 方法 (Delegate) :在擁有此控制元件的基礎視窗控制代碼的執行緒上執行指定的委託。 Control.BeginInvoke 方法 (Delegate) :在建立控制元件的基礎控制代碼所線上程上非同步執行指定委託。 (一)Control的

C# 中的invokebegininvoke

原文地址:http://www.cnblogs.com/Z-King/archive/2011/11/03/2234337.html   1. control中的invoke、begininvoke。   2. delegrate中的invoke、begininvoke

C# Control的InvokeBeginInvoke

之前在專案中遇到了UI介面更新出錯的問題,後來在網上找了很多資料,終於解決,先將資料整理如下: 為什麼需要Control.Invoke和Control.BeginInvoke?? 如果從另外一個執行緒操作 windows窗體上的控制元件,就會和主執行緒產生競爭,造成不可

C# InvokeBeginInvoke理解

       在Invoke或者BeginInvoke的使用中無一例外地使用了委託Delegate,Invoke或者BeginInvoke方法都需要一個委託物件作為引數。委託類似於回撥函式的地址,因此呼叫者通過這兩個方法就可以把需要呼叫的函式地址封送給介面執行緒。這些方法裡面

WPF的Invoke()BeginInvoke()

(1)A在UI執行緒上執行完後,開始BeginInvoke,BeginInvoke是非同步(2)InvokeMethod方法,即程式碼段C不會執行,而是立即在UI執行緒上執行程式碼段B。(3)程式碼段B執行完後(就是說butBeginInvoke_Click方法執行完後),InvokeMethod方法,即程式

【分析】淺談C#中Control的InvokeBeginInvoke在主副線程中的執行順序區別(SamWang)

info start result 初步 總結 inter blank rap 傳遞   今天無意中看到有關Invoke和BeginInvoke的一些資料,不太清楚它們之間的區別。所以花了點時間研究了下。   據msdn中介紹,它們最大的區別就是BeginInvoke屬於

C#中有關資源、BeginInvoke, Invoke事件的事情

  事情是這麼來的,我開發的一個程式報了一個錯誤 “在建立視窗控制代碼之前,不能在控制元件上呼叫 Invoke 或 BeginInvoke錯誤”。 然後我在網上查資料,發現一個有意思的問題,文章出處為“在建立視窗控制代碼之前,不能在控制元件上呼叫 Invoke 或 BeginInvoke”錯誤。

跨線程調用控件 InvokeBeginInvoke 區別

static pan textbox string new log action add this public delegate void Add_B(object x); List&l

.net 在創建窗口句柄之前,不能在控件上調用 InvokeBeginInvoke

使用 ole ted 線程 他能 啟動 用法 cat som 窗體句柄的創建 窗口創建時,窗口並沒有創建句柄,只有Application.Run(form)或者form.Show()之後才有句柄,即窗口只有顯示或者啟動消息循環後才有句柄!如果創建form之後,主線程中調用f

Unity延時方法InvokeInvokeRepeating

執行 多少秒 int line deb avi delay 重復執行 gin Unity延時方法Invoke和InvokeRepeating MonoBehaviour裏面有兩個內置的延時方法 InvokeRepeating(methodName: str

InvokeBeginInvoke,EndInvoke

gpo com doc sta display .get ini invoke 傳遞 (一)使用規則 public IAsyncResult BeginInvoke(Delegate method);public IAsyncResult BeginInvoke(Deleg

645. Set Mismatch挑出不匹配的元素應該真正存在的元素

總結 優化 present turn space oss exit hset RR [抄題]: he set S originally contains numbers from 1 to n. But unfortunately, due to the data erro