c# Delegate.BeginInvoke() 和 thread ID
c# Delegate.BeginInvoke() 和 thread 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
c# Delegate.BeginInvoke()和线程ID问题的出现原因是因为一个关于委托的问题在Stack Overflow上被误解了。接受的答案声称Delegate.BeginInvoke()方法并不会创建一个单独的线程,而是在调用者的线程中执行代码。这让提问者产生了困惑,因为他一直以为BeginInvoke()方法会从线程池中获取一个线程并在其中执行代码。通过查看代码示例,他意识到自己误解了问题,该问题实际上是关于Windows Forms中的动态调用,而不是简单的委托方法调用。
这个问题的解决方法是通过查看代码示例和仔细阅读关于BeginInvoke()方法的文档来纠正误解。提问者意识到自己之前对BeginInvoke()方法的理解是正确的,它确实会从线程池中获取一个线程并在其中执行代码。并且他还发现了Control.BeginInvoke()/Dispatcher.BeginInvoke()方法的命名非常令人困惑,因为它们实际上并不创建线程。
最后,提问者还向Stack Overflow上的专家提问了如何记住代码的问题,并提到了Jon Skeet记住应用程序空闲事件的答案。
总之,c# Delegate.BeginInvoke()和线程ID问题的出现是因为一个关于委托的问题被误解了。解决方法是通过查看代码示例和仔细阅读文档来纠正误解。同时,提问者还提到了其他关于记住代码的问题。
在C#中,使用Delegate.BeginInvoke()方法来异步调用委托对象。然而,有时候在使用Delegate.BeginInvoke()方法时,可能会遇到线程ID(Thread ID)不一致的问题。
出现这个问题的原因可能是由于Delegate.BeginInvoke()方法默认使用线程池(ThreadPool)来执行委托对象。线程池是一组可重用的线程,它们可以被分配给执行任务。由于线程池中的线程是可重用的,所以在每次调用Delegate.BeginInvoke()方法时,可能会分配给不同的线程来执行委托对象。
当使用Delegate.BeginInvoke()方法时,如果需要获取当前线程的ID,可能会出现线程ID不一致的问题。因为每次调用Delegate.BeginInvoke()方法时,可能都会分配给不同的线程执行,所以获取到的线程ID也会不同。
为了解决这个问题,可以使用Thread.CurrentThread.ManagedThreadId属性来获取当前线程的ID。这个属性返回一个整数,表示当前线程的唯一标识符。
下面是一个示例代码,演示了如何使用Thread.CurrentThread.ManagedThreadId属性来获取当前线程的ID:
using System; using System.Threading; class Program { static void Main() { Action action = () => { Console.WriteLine("Thread ID: " + Thread.CurrentThread.ManagedThreadId); }; action.BeginInvoke(null, null); Console.WriteLine("Main Thread ID: " + Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); } }
运行上述代码,你会发现Delegate.BeginInvoke()方法的执行线程ID与主线程的ID是不一致的。
总之,当使用Delegate.BeginInvoke()方法时,可能会遇到线程ID不一致的问题。为了解决这个问题,可以使用Thread.CurrentThread.ManagedThreadId属性来获取当前线程的ID。