2009-08-04 75 views
20

我有一個基於對話框的應用程序,我將其中的I/O操作讀寫委託給不同的線程。BeginInvoke和Thread.Start之間的區別

我只是想明確的是有兩種方法之間有什麼區別..

第一種方法:(我這樣做的,我的主要形式-Form.cs)

delegate void Action(); 
Action _action = new Action(Method); 
this.BeginInvoke(_action); 

第二種方法:

Thread th = new Thread(new ThreadStart(_action)); 
th.Start(); 

我注意到的BeginInvoke掛在UI進行了第二,而第二種方法不..

請幫忙

+4

有關信息,請明確說明您是否指Control.BeginInvoke和Delegate.BeginInvoke;我相信你的意思是第一個,但他們幾乎是完全相反的,所以區別很重要。 – 2009-08-04 09:34:32

+0

它是第一種方法(Control.BeginInvoke),因爲我在表單上執行此操作。 – 2009-08-04 09:42:27

回答

17

BeginInvoke將在消息泵的消息隊列中的動作發佈在與Form相同的線程上,它不會創建新的線程。

Control.BeginInvoke行爲類似於異步線程啓動,但具有重要的內部差異。

進一步閱讀文章here

0

區別在於BeginInvoke方法只是在SAME線程上異步調用委託。

使用Thread.Start,您將創建一個完全不同的線程。

Thread.Start一定會給你更好的表現!

+1

更好的性能是一個假設...有一個線程,你將遇到舊的CrossThreadedExceptions ... – Pondidum 2009-08-04 09:31:14

8

BeginInvokes通過在窗口中發佈消息,在UI線程上異步執行委託(這就是爲什麼會掛起UI)。如果委託中的代碼訪問用戶界面,那就是你需要做的事情。

Thread.Start的方法在新的獨立線程上執行委託。

3

Thread.Start在您的新Thread上運行它。

Control.BeginInvoke在該控件所屬的線程上運行該方法。如果您當前位於控件的線程中,則只有在將控制權返回給消息循環時纔會運行該方法,例如,退出你的事件處理器。

3

試試這個。

class Form1: Form 
{ 
    public void ButtonWasClicked(object sender, EventArgs e) 
    { 
     /* Call the UI's Invoke() method */ 
     this.Invoke((MethodInvoker)delegate() 
     { 
      /* Stuff to do.. you can access UI elements too without 
      * the nasty "Control accessed from another thread.." 
      * Use BeginInvoke() only if you have code after this section 
      * that you want the UI to execute without waiting for this 
      * inner blockto finish. 
      */ 
     }); 
    } 
} 

關於BeginInvoke的(),它是用來使函數將立即返回並無需等待完成該方法的下一行就會被執行等,等等。

不同之處在於,如果您創建了一個線程,就可以像對待其他線程一樣對它進行更多的控制。您將遇到CrossThreadExceptions!而如果您使用IAsyncResult和BeginInvoke(),則您將無法控制異步操作​​的執行流程,因爲它由運行時管理。

通過調用,您還可以向方法發送更多參數並在操作完成後調用方法。

MyDelegateWithTwoParam del = new MyDelegateWithTwoParam(_method); 
AsyncCallback callback = new AsyncCallback(_callbackMethod); 
IAsyncResult res = del.BeginInvoke(param1, param2, callback, null); 

private void _callbackMethod(IAsyncResult iar) { 
    /* In this method you can collect data that your operation might have returned. 
    * If MyDelegateWithTwoParam has a return type, you can find out here what i was. */ 
} 

我已經廣泛用於UI開發。我會更多地使用線程來處理類似服務的對象。 (想象一個停留並監聽TCP連接的對象)以及用於UI後臺工作的異步方法(也可以看看BackgroundWorker)。 如果第一種方法需要額外的一秒才能開始,請不要擔心:Thread.Abort()不是 始終是您的最佳解決方案。試試你的程序代碼中的_abort標誌並鎖定它。

希望我已經回答了這個問題。

利奧Bruzzaniti

1

正如其他已經公佈,Thread.Start將推出一個新的線程,如果你想改變一個字段的值Control.BeginInvoke()將運行在UI線程上的代碼(必要的,例如)。

但是,我發現在WinForms中執行後臺任務最簡單的方法是使用BackgroundWorker。將它放到表單上,連接事件,然後調用RunWorkerAsync()。然後在DoWork事件中編寫後臺任務。任何UI刷新都可以放入RunWorkerCompleted事件中。

使用BackgroundWorker可以避免所有煩人的線程處理和IsInvokeRequired東西。

下面是更詳細的how-to article

相關問題