首頁  >  文章  >  後端開發  >  C# Invoke 與 BeginInvoke之間的差異詳解

C# Invoke 與 BeginInvoke之間的差異詳解

零下一度
零下一度原創
2017-06-28 15:38:211778瀏覽

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

參考以下程式碼:

public delegate void treeinvoke();private void UpdateTreeView()
{
   MessageBox.Show(System.Threading.Thread.CurrentThread.Name);
}private void button1_Click(object sender, System.EventArgs e)
{
   System.Threading.Thread.CurrentThread.Name = "UIThread";
  View ;
}

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

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

我們再看下面的程式碼:

public delegate void treeinvoke();private void UpdateTreeView()
{
   MessageBox.Show(Thread.CurrentThread.Name);
}private void button1_Click(object sender, System.EventArgs e)
{
   Thread.CurrentThread.Name = "UIThread";
   Thread th = new Thread(new ThreadStart(StartThread)); ##    th.Start();
}private void StartThread()
{
   Thread.CurrentThread.Name = "Work Thread";
   treeView1.BeginInvoke(new treeinvokeView(Update   treeView1.BeginInvoke(new treeinvokeView(Updateree );#Tree ); ##}


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

那 BeginInvoke 究竟有什麼用呢?

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

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

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

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

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

private void 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();##  if (i%100 == 0) Application.DoEvents();##  ##

以上是C# Invoke 與 BeginInvoke之間的差異詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn