有没有办法确定使用BeginInvoke时执行处理程序的线程?

时间:2011-02-10 13:47:48

标签: c# .net multithreading asynchronous delegates

我想确定使用BeginInvoke时执行处理程序的线程。 现在每次我调用该方法时,处理程序都由另一个线程执行。有没有办法确定线程?

using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace Delegate
{
  public delegate void BarDelegate(string argument);

  public class Foo
  {
    private void handleBar(string argument)
    {
      int threadId = AppDomain.GetCurrentThreadId();
      Console.WriteLine("Argument is " + argument + " " + threadId.ToString());
    }

    public void bar(string argument)
    {
      BarDelegate smd = new BarDelegate(this.handleBar);
      smd.BeginInvoke(argument, null, null);
    }

    public static void Main()
    {
      Console.WriteLine(AppDomain.GetCurrentThreadId().ToString());
      Foo ds = new Foo();
      ds.bar("Hello, world!");
      Console.ReadLine();
      ds.bar("Hello, world!");
      Console.ReadLine();
    }
  }
}

3 个答案:

答案 0 :(得分:4)

获取异步代码以在特定线程上执行需要同步提供程序。 .NET框架中有两个主要的,WindowsFormsSynchronizationContext,它帮助Control.BeginInvoke()在UI线程上运行代码。和DispatcherSynchronizationContext,支持WPF的Dispatcher.BeginInvoke()。为这些类库调用Application.Run()时,将自动安装这些提供程序。他们只能调用UI线程。

控制台模式程序没有同步提供程序。并且委托的BeginInvoke()方法总是在线程池线程上执行。如果您不能使用这些类库,并且您使用的组件不支持多线程(除非它是COM服务器,否则很少使用),那么使用线程不是您可以使用的选项。

答案 1 :(得分:2)

这是因为BeginInvoke使用着名的AppDomain ThreadPool

如果您需要知道哪个线程执行它 - 并且您真的需要 - 那么您可能需要创建自己的线程。 ThreadPool(就此而言BeginInvoke)是我们需要做些什么而不关心如何以及何时做的事情。

答案 2 :(得分:0)

我认为您真正想要的是控制异步任务在哪个线程中运行。您不能使用BeginInvoke,因为它使任务在.NET ThreadPool的随机线程中运行。因此,您需要先创建一个线程,然后将任务发布到它,这样您就可以控制。如果您不想自己编写,我建议您使用SmartThreadPool,只需谷歌。