默认情况下,在控制台应用程序中,异步任务将在ThreadPool
上运行,这意味着多个任务可以在不同的线程上并行运行(如果您有多核处理器,也会这样做).
我如何才能禁止Task
在我的控制台应用程序中并行运行(不使用互斥体;我不想处理公平性问题并记住在任何地方锁定互斥体)?我希望一次只运行一个并发任务(即,我希望任务是并发的,但不是并行的).
我曾try 将线程池中的最大线程数设置为1,但线程池运行时的线程数不能少于CPU的核心数,因此无法正常运行.
默认情况下,在控制台应用程序中,异步任务将在ThreadPool
上运行,这意味着多个任务可以在不同的线程上并行运行(如果您有多核处理器,也会这样做).
我如何才能禁止Task
在我的控制台应用程序中并行运行(不使用互斥体;我不想处理公平性问题并记住在任何地方锁定互斥体)?我希望一次只运行一个并发任务(即,我希望任务是并发的,但不是并行的).
我曾try 将线程池中的最大线程数设置为1,但线程池运行时的线程数不能少于CPU的核心数,因此无法正常运行.
您可以使用Stephen Cleary在AsyncExNuGet包中找到的Static AsyncContext
类在控制台应用程序上安装单线程同步上下文:
AsyncContext.Run(async () =>
{
await Foo();
await Task.WhenAll(items.Select(async item =>
{
var result = await Bar(item);
DoStuff(result);
}));
await FooBar();
});
AsyncContext.Run
是一个阻塞调用,类似于Application.Run
方法.它在当前线程上安装一个特殊的AsyncContextSynchronizationContext
,就像Application.Run
在UI线程上安装WindowsFormsSynchronizationContext
一样.只要AsyncContext.Run
委托内的所有await
都具有默认配置,这意味着没有ConfigureAwait(false)
附加到它们,则每个await
之后的所有延续都将在控制台应用程序的主线程上运行.Your代码将是单线程的.任何内置的异步方法可能仍然在幕后使用ThreadPool
个线程来完成它们的工作,但是your代码不会观察到这些其他线程,也不会受到它们的影响.
AsyncContext.Run
在异步action
委托以及可能已在该委托内调用的任何async void
方法完成时完成.相反,任何悬而未决的 ignition 和忘记任务都不会阻止AsyncContext.Run
的完成,并且会被留在永远不完整的状态中.AsyncContext.Run
完成后,AsyncContextSynchronizationContext
将被卸载.SynchronizationContext.Current
将恢复到其原始状态.
注意不要在委托中使用.Wait()
或.Result
,否则程序会死锁.如果您阻塞了执行代码的唯一线程,您的程序将陷入停顿.