2011-04-05 64 views
1

讓我們說我們有一些簡單的代碼是這樣的:C#Delegate.BeginInvoke()和線程ID

private static void Main() 
{ 
    Console.WriteLine("Main thread {0}\n", Thread.CurrentThread.ManagedThreadId); 

    Action asyncCaller1 =() => LongPerfomingTask(5); 
    Action asyncCaller2 =() => LongPerfomingTask(3); 

    var asyncResult1 = asyncCaller1.BeginInvoke(null, null); 
    var asyncResult2 = asyncCaller2.BeginInvoke(null, null); 

    asyncResult1.AsyncWaitHandle.WaitOne(); 
    asyncResult2.AsyncWaitHandle.WaitOne(); 

    Console.WriteLine("Done"); 
} 

private static void LongPerfomringTask(int seconds) 
{ 
    Thread.Sleep(TimeSpan.FromSeconds(seconds)); 

    Console.WriteLine("Thread {0} finished execution", Thread.CurrentThread.ManagedThreadId); 
} 

Delegate.BeginInvoke()不創建一個線程,它在調用者的線程中執行代碼時,它是在空閒狀態下,右那麼,爲什麼這個示例應用程序的輸出是這樣的:?

Main thread 1 

Thread 4 finished execution 
Thread 3 finished execution 
Done 

回答

6

沒有,Delegate.BeginInvoke使用線程池。總是。除非你正在考慮將任務添加到UI消息隊列中,否則沒有「在調用者的線程中空閒時執行」的概念......你是否對Control.BeginInvoke/Dispatcher.BeginInvoke感到困惑?

在這種情況下,您已經有了一個控制檯應用程序 - 沒有任何信息可以用來啓動。

+0

我被一些後上感到困惑代表SO(接受的答案是像「Delegate.BeginInvoke()不創建一個單獨的線程 - 代碼正在調用者的線程中執行)。我一直認爲BeginInvoke()方法從一個線程池中取出一個線程並在那裏執行代碼,現在我確信。謝謝。順便說一句,我發現Control.BeginInvoke()/ Dispatcher.BeginInvoke()的名字很奇怪,那是因爲它們實際上不會創建線程。我認爲這些方法被命名爲非常混淆 – 2011-04-05 14:50:05

+0

@taras:隨意指向該線程,以便我可以更正其他:) – 2011-04-05 14:51:50

+0

http://stackoverflow.com/questions/1909839/invoke-and-begininvoke我可能誤解了這個問題,我在你的回答後仔細檢查了一遍,發現一切似乎都很好。我不是很仔細地閱讀代碼示例(搜索關於動態調用的SO,所以我認爲我被指向'代理線程'),它是WF示例,不是普通的委託方法調用 – 2011-04-05 15:02:48

0

@ taras.roshko:這是提高你的線程池的理解資源: Chapter on Threading

+1

謝謝,但我已經閱讀過了:)當然,這是一篇很棒的文章 – 2011-04-06 07:57:47