2011-04-05 88 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