C#异步/等待有/没有等待(即发即忘)
我有以下代码:
static async Task Callee() {
await Task.Delay(1000);
}
static async Task Caller()
{
Callee(); // #1 fire and forget
await Callee(); // #2 >1s
Task.Run(() => Callee()); // #3 fire and forget
await Task.Run(() => Callee()); // #4 >1s
Task.Run(async () => await Callee()); // #5 fire and forget
await Task.Run(async () => await Callee()); // #6 >1s
}
static void Main(string[] args)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
Caller().Wait();
stopWatch.Stop();
Console.WriteLine($"Elapsed: {stopWatch.ElapsedMilliseconds}");
Console.ReadKey();
}
#1以最简单的方式解雇。#2只是等待。有趣的东西从#3开始。通话背后的深入逻辑是什么?
我知道在ASP.NET中使用fire’n’forget作为警告的指向这里。我之所以这么问,是因为我们将应用程序移到了不再可以使用的服务结构上,HostingEnvironment.QueueBackgroundWorkItem(async
cancellationToken => await LongMethodAsync());建议将其替换为Task.Run
。
我看到Task.Run运行了一个新线程,那么#3和#5之间会有什么区别?
回答:
我之所以这么问,是因为我们将应用程序移至服务结构,因此我们不再可以使用HostingEnvironment.QueueBackgroundWorkItem(async
cancelleToken => await LongMethodAsync());。建议是简单地将其替换为Task.Run。
那是个坏建议。您应该使用一个独立的后台进程,该进程通过队列与Web前端分开。
通话背后的深入逻辑是什么?
- 在当前线程上启动异步方法。忽略所有结果(包括异常)。
- 在当前线程上启动异步方法。异步等待它完成。这是调用异步代码的标准方法。
- 在线程池线程上启动异步方法。忽略所有结果(包括异常)。
- 在线程池线程上启动异步方法。异步等待它完成。
- 与#3完全相同。
- 与#4完全相同。
以上是 C#异步/等待有/没有等待(即发即忘) 的全部内容, 来源链接: utcz.com/qa/411809.html