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 的时候并想象的那么简单。 下面我们还是通过一个错误的示例开始讲解如何正确的使用它。
阅读全文