长时间运行的任务中的 ConfigureAwait(false)

ConfigureAwait(false) in long running task

提问人:Duagt 提问时间:9/30/2023 更新时间:9/30/2023 访问量:123

问:

我可能对某些事情有误解。 对我来说,在异步方法中,有 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”任务创建创建的专用线程上执行,因此这与从一开始就在线程池上执行任务相同。

如果我错了,请纠正我。

C# .NET 异步 任务 configureawait

评论

0赞 Theodor Zoulias 9/30/2023
顺便说一句,除非类型是你做错了什么。有关说明,请参阅此问题_managementTaskTask<Task>

答:

2赞 Stephen Cleary 9/30/2023 #1

这是正确的,这就是为什么对委托几乎总是无用的。LongRunningasync

此外,如果当前没有任务调度程序(通常没有),那么任何 ,无论有没有 ,都是如此。awaitConfigureAwait(false)

顺便说一句,这只是对线程池的提示。它不保证专用线程。LongRunning

作为一般规则,用于将异步工作调度到线程池,而不是 .Task.RunTask.Factory.StartNew

评论

0赞 Duagt 10/1/2023
您能告诉我更多关于任务计划程序方面的信息吗?
0赞 Duagt 10/1/2023
如果我想要一个用于性能目的的专用线程,我该怎么办?就像一个非常高优先级的任务
0赞 Theodor Zoulias 10/1/2023
@Duagt只是不要使用 .看看这个问题:LongRunning Task 行为async
0赞 Stephen Cleary 10/1/2023
@Duagt:我有一篇博客文章,其中有更多细节:默认情况下将使用当前的任务计划程序。通常没有一个,在这种情况下,将在线程池上运行委托。 始终在线程池上运行其委托。如果代码位于线程池上,则 await 不会捕获上下文,因此与 相同。StartNewStartNewTask.RunConfigureAwait(false)ConfigureAwait(true)
1赞 Theodor Zoulias 10/4/2023
@Duagt理想情况下,您会希望找到饱和问题的解决方案。拥有饱和的线程池会带来麻烦。既然你已经放弃了,那么专用线程是下一个不错的选择。只要确保你没有结合和.必须是同步的。将所有替换为 以保留在专用线程上。上的完整,因此将其替换为 。LongRunningasyncactionawait.GetAwaiter().GetResult()Task.DelayThreadPoolThread.Sleep