溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C# Invoke和BeginInvoke之間的區(qū)別是什么

發(fā)布時(shí)間:2020-09-09 11:06:59 來(lái)源:億速云 閱讀:177 作者:小新 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān) C# Invoke和BeginInvoke之間的區(qū)別是什么,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

參考以下代碼:

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";
   treeView1.BeginInvoke(new treeinvoke(UpdateTreeView));
}

看看運(yùn)行結(jié)果,彈出的對(duì)話框中顯示的是 UIThread,這說(shuō)明 BeginInvoke 所調(diào)用的委托根本就是在 UI 線程中執(zhí)行的。

既然是在 UI 線程中執(zhí)行,又何來(lái)“異步執(zhí)行”一說(shuō)呢?

我們?cè)倏纯聪旅娴拇a:

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 treeinvoke(UpdateTreeView));
}

再看看運(yùn)行結(jié)果,彈出的對(duì)話框中顯示的還是 UIThread,這說(shuō)明什么?這說(shuō)明 BeginInvoke 方法所調(diào)用的委托無(wú)論如何都是在 UI 線程中執(zhí)行的。

那 BeginInvoke 究竟有什么用呢?

在多線程編程中,我們經(jīng)常要在工作線程中去更新界面顯示,而在多線程中直接調(diào)用界面控件的方法是錯(cuò)誤的做法,具體的原因可以在看完我的這篇之后看看這篇:在多線程中如何調(diào)用Winform,如果你是大牛的話就不要看我這篇了,直接看那篇吧,反正那篇文章我沒(méi)怎么看懂。

Invoke 和 BeginInvoke 就是為了解決這個(gè)問(wèn)題而出現(xiàn)的,使你在多線程中安全的更新界面顯示。

正確的做法是將工作線程中涉及更新界面的代碼封裝為一個(gè)方法,通過(guò) Invoke 或者 BeginInvoke 去調(diào)用,兩者的區(qū)別就是一個(gè)導(dǎo)致工作線程等待,而另外一個(gè)則不會(huì)。

而所謂的“一面響應(yīng)操作,一面添加節(jié)點(diǎn)”永遠(yuǎn)只能是相對(duì)的,使 UI 線程的負(fù)擔(dān)不至于太大而以,因?yàn)榻缑娴恼_更新始終要通過(guò) UI 線程去做,我們要做的事情是在工作線程中包攬大部分的運(yùn)算,而將對(duì)純粹的界面更新放到 UI 線程中去做,這樣也就達(dá)到了減輕 UI 線程負(fù)擔(dān)的目的了。

而在那段更新樹(shù)節(jié)點(diǎn)的代碼中,其實(shí)唯一起作用的代碼是:System.Threading.Thread.Sleep(100);,它使 UI 線程有了處理界面消息的機(jī)會(huì),其實(shí) 數(shù)碼幽靈 將問(wèn)題復(fù)雜化了,只要以下的代碼就可以很好的工作了。

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();
   }
}

關(guān)于 C# Invoke和BeginInvoke之間的區(qū)別是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI