【发布时间】:2018-09-21 20:11:30
【问题描述】:
当其中一个异步处于活动循环中时,我观察到 CancellationTokenSource.Cancel 挂起。
完整代码:
static async Task doStuff(CancellationToken token)
{
try
{
// await Task.Yield();
await Task.Delay(-1, token);
}
catch (TaskCanceledException)
{
}
while (true) ;
}
static void Main(string[] args)
{
var main = Task.Run(() =>
{
using (var csource = new CancellationTokenSource())
{
var task = doStuff(csource.Token);
Console.WriteLine("Spawned");
csource.Cancel();
Console.WriteLine("Cancelled");
}
});
main.GetAwaiter().GetResult();
}
打印Spawned 并挂起。调用堆栈看起来像:
ConsoleApp9.exe!ConsoleApp9.Program.doStuff(System.Threading.CancellationToken token) Line 23 C#
[Resuming Async Method]
[External Code]
ConsoleApp9.exe!ConsoleApp9.Program.Main.AnonymousMethod__1_0() Line 34 C#
[External Code]
取消await Task.Yield 将导致Spawned\nCancelled 输出。
任何想法为什么? C# 是否保证一次生成的异步永远不会阻塞其他异步?
【问题讨论】:
-
re:你的注释代码,
await Task.Delay(TimeSpan.MaxValue, token)抛出一个参数异常,所以永远不会碰到你的while (true),所以你不会坚持下去。Timeout.InfiniteTimeSpan将是您意图的适当论据。 -
>> 你的注释代码,await Task.Delay(TimeSpan.MaxValue, token) 抛出一个参数异常,所以永远不会碰到你的 while (true) 权利
-
>> 从哪里开始;可以从指向文档开始,据说
CancellationTokenSource.Cancel可以切换上下文
标签: c# .net async-await cancellationtokensource