Kid*_*ice 2 c# multithreading task-parallel-library async-await cancellation-token
我正在尝试使用取消令牌从另一个线程中跳出循环:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace CancellationTokenTest
{
class Program
{
private static CancellationTokenSource token;
static async Task Main(string[] args)
{
token = new CancellationTokenSource();
var t1 = LongProcess1();
for (int i = 0; i < 5; i++)
{
try
{
await Task.Delay(2000, token.Token);
Console.WriteLine($"Main awaited {i}");
}
catch (OperationCanceledException)
{
break;
}
}
Console.WriteLine("Main loop completed");
t1.Wait();
Console.WriteLine("Application end");
}
static async Task LongProcess1()
{
for (int i = 0; i < 5; i++)
{
await Task.Delay(1000);
Console.WriteLine($"LongProcess1 awaited {i}");
}
Console.WriteLine("Submitting cancel");
token.Cancel(); // <------ Blocking execution
Console.WriteLine("Cancellation done!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是该行Console.WriteLine("Cancellation done!");永远不会被执行,并且该Main()方法一直在等待t1完成。
我不理解为什么!
我在 .NET 5 上运行它,但它似乎不依赖于框架。有人可以帮助我了解发生了什么吗?
这种僵局几乎与我博客中描述的僵局一模一样。您需要注意的一件事是,CancellationTokenSource.Cancel在这种情况下,在调用Cancel.
所以,这就是正在发生的事情:
Main开始LongProcess。LongProcess使用 some awaits 并在线程池线程上恢复。Main正在做一个await Task.Delay.LongProcess时候执行Cancel,它实际上会继续在当前线程上执行该Main方法。您可以通过在块中放置断点并查看调用堆栈来验证这一点。catch.Wait()) 上。LongProcess无法完成,因为当前运行它的线程被阻塞,等待它完成。要修复它,请将 更改Wait()为await。
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |