我想确定使用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();
}
}
}
答案 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,只需谷歌。