提问人:Duagt 提问时间:9/30/2023 更新时间:9/30/2023 访问量:123
长时间运行的任务中的 ConfigureAwait(false)
ConfigureAwait(false) in long running task
问:
我可能对某些事情有误解。 对我来说,在异步方法中,有 ConfigureAwait(false);将允许任务继续在线程池上执行。
因此,如果我在专用线程上声明一个 LongRunning 任务,用于后台工作(例如检查队列上的一些工作)
_managementTask = Task.Factory.StartNew(async () =>
{
while (!_cancellationToken.IsCancellationRequested)
{
await Task.Delay(10000, _cancellationToken).ConfigureAwait(false);
await CheckWork().ConfigureAwait(false);
}
}, TaskCreationOptions.LongRunning);
然后这意味着,由于第一个 ConfigureAwait(false),以下所有代码和循环都将在线程池上执行,而不是在“LongRunning”任务创建创建的专用线程上执行,因此这与从一开始就在线程池上执行任务相同。
如果我错了,请纠正我。
答:
2赞
Stephen Cleary
9/30/2023
#1
这是正确的,这就是为什么对委托几乎总是无用的。LongRunning
async
此外,如果当前没有任务调度程序(通常没有),那么任何 ,无论有没有 ,都是如此。await
ConfigureAwait(false)
顺便说一句,这只是对线程池的提示。它不保证专用线程。LongRunning
作为一般规则,用于将异步工作调度到线程池,而不是 .Task.Run
Task.Factory.StartNew
评论
0赞
Duagt
10/1/2023
您能告诉我更多关于任务计划程序方面的信息吗?
0赞
Duagt
10/1/2023
如果我想要一个用于性能目的的专用线程,我该怎么办?就像一个非常高优先级的任务
0赞
Stephen Cleary
10/1/2023
@Duagt:我有一篇博客文章,其中有更多细节:默认情况下将使用当前的任务计划程序。通常没有一个,在这种情况下,将在线程池上运行委托。 始终在线程池上运行其委托。如果代码位于线程池上,则 await
不会捕获上下文,因此与 相同。StartNew
StartNew
Task.Run
ConfigureAwait(false)
ConfigureAwait(true)
1赞
Theodor Zoulias
10/4/2023
@Duagt理想情况下,您会希望找到饱和问题的解决方案。拥有饱和的线程池会带来麻烦。既然你已经放弃了,那么专用线程是下一个不错的选择。只要确保你没有结合和.必须是同步的。将所有替换为 以保留在专用线程上。上的完整,因此将其替换为 。LongRunning
async
action
await
.GetAwaiter().GetResult()
Task.Delay
ThreadPool
Thread.Sleep
评论
_managementTask
Task<Task>