有/无等待的异步/等待(即发即忘) [英] Async/await with/without awaiting (fire and forget)

查看:40
本文介绍了有/无等待的异步/等待(即发即忘)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

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 开始.调用背后的深层逻辑是什么?

#1 fires and forgets in the most simple way. #2 simply waits. Interesting stuff begins from #3 on. What's the in-depth logic behind the calls?

我知道在 ASP.NET 中使用 fire'n'forget 警告 这里.我问这个,因为我们正在将我们的应用程序移动到服务结构,我们不再可以使用 HostingEnvironment.QueueBackgroundWorkItem(asyncCancellationToken => await LongMethodAsync()); 并且建议是简单的用 Task.Run 替换它.

I'm aware of using fire'n'forget caveats in ASP.NET as pointed here. I'm asking this, because we're moving our app to service fabric where we no longer can use HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => await LongMethodAsync()); and the advice is to simply replace it with Task.Run.

我看到Task.Run运行了一个新线程,那么#3和#5有什么区别?

I see that Task.Run runs a new thread, what would be the difference between #3 and #5 then?

推荐答案

我问这个,因为我们正在将我们的应用程序移动到服务结构,在那里我们不能再使用 HostingEnvironment.QueueBackgroundWorkItem(asyncCancellationToken => await LongMethodAsync());建议是简单地用 Task.Run 替换它.

I'm asking this, because we're moving our app to service fabric where we no longer can use HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken => await LongMethodAsync()); and the advice is to simply replace it with Task.Run.

这是个糟糕的建议.您应该使用 单独的后台进程队列中的 Web 前端.

That's bad advice. You should use a separate background process separated from your web frontend by a queue.

调用背后的深层逻辑是什么?

What's the in-depth logic behind the calls?

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

这篇关于有/无等待的异步/等待(即发即忘)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆