LongRunningTask如何正确使用?
摘要:在上一篇文章《如何正确实现一个 BackgroundService》中有提到 LongRunning 来优化后台任务始终保持在同一个线程上。 protected override Task ExecuteAsync(Cancellation
在上一篇文章《如何正确实现一个 BackgroundService》中有提到 LongRunning 来优化后台任务始终保持在同一个线程上。
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
return Task.Factory.StartNew(async () =>
{
while (!stoppingToken.IsCancellationRequested)
{
// Simulate some work
Console.WriteLine("HostServiceTest_A is doing work.");
LongTermTask();
await Task.Delay(1000, stoppingToken); // Delay for 1 second
}
Console.WriteLine("HostServiceTest_A task done.");
}, TaskCreationOptions.LongRunning);
}
private void LongTermTask()
{
// Simulate some work
Console.WriteLine("LongTermTaskA is doing work.");
Thread.Sleep(30000);
}
但是被黑洞视界 大佬指出这个用法是错误的:以上用法并不能保证任务始终在同一个 Task(线程) 上执行。原因是当碰到第一个 await 之后运行时会从 ThreadPool 中调度一个新的线程来执行后面的代码,而当前线程被释放。这个时候就不符合我们使用 LongRunning 的期望了。
在 .NET 中,Task.Factory.StartNew 提供了 TaskCreationOptions.LongRunning 选项,很多开发者会用它来启动长时间运行的任务,并且想当然的认为它会永远执行在同一个线程上。但是事实上当遇到 async await 的时候并想象的那么简单。
下面我们还是通过一个错误的示例开始讲解如何正确的使用它。
