c# Delegate.BeginInvoke() 和 thread ID

6 浏览
0 Comments

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

0
0 Comments

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问题的出现是因为一个关于委托的问题被误解了。解决方法是通过查看代码示例和仔细阅读文档来纠正误解。同时,提问者还提到了其他关于记住代码的问题。

0
0 Comments

在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。

0