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前端分开。

通话背后的深入逻辑是什么?

  1. 在当前线程上启动异步方法。忽略所有结果(包括异常)。
  2. 在当前线程上启动异步方法。异步等待它完成。这是调用异步代码的标准方法。
  3. 在线程池线程上启动异步方法。忽略所有结果(包括异常)。
  4. 在线程池线程上启动异步方法。异步等待它完成。
  5. 与#3完全相同。
  6. 与#4完全相同。

以上是 C#异步/等待有/没有等待(即发即忘) 的全部内容, 来源链接: utcz.com/qa/411809.html

回到顶部