有没有一种方法可以在没有Task的情况下强制上下文切换.异步代码中的延迟



我的代码看起来像:

我试图避免把它放在一个任务。运行,因为它是异步的,应该在主线程上运行良好

然而,它不做上下文切换(并将永远运行),除非我插入一个任务。延迟进入循环

有没有更好的方法来实现这个(没有Task.Run)?

var tasks = new List<Task>();
var cts = new CancellationTokenSource();
tasks.Add(DoSomething(cts.Token));
cts.Cancel();
Task.WaitAll(tasks.ToArray());
Console.WriteLine("Done");
async Task DoSomething(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
await Task.CompletedTask;
await Task.Delay(1); // Without this is doesn't do context switch
}
}

我在尝试取消单元测试时,工作负载很重,遇到了这个问题。

Try

async Task DoSomething(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
//await Task.CompletedTask; //you can omit this line
await Task.Yield();
}
}

如果您想模拟一个可取消的操作,最简单的方法可能是:

Task DoSomething(CancellationToken cancellationToken)
{
return Task.Delay(Timeout.Infinite, cancellationToken);
}

cancellationToken参数具有取消语义,即当令牌被取消时,Task将转移到Canceled状态。如果您希望它具有停止语义,这是CancellationToken的非标准语义,您可以这样做:

async Task DoSomething(CancellationToken stoppingToken)
{
try { await Task.Delay(Timeout.Infinite, stoppingToken); }
catch (OperationCanceledException) { }
}

现在,当令牌被取消时,Task将过渡到RanToCompletion状态。请注意,在标准。net库中很少看到带有停止语义的CancellationToken参数。

相关内容

  • 没有找到相关文章

最新更新