启动和异步即发即弃调用的正确方法?

sil*_*ent 2 .net c# task-parallel-library async-await .net-core

我有一个异步调用 ( DoAsyncWork()),我想以一种即发即弃的方式开始,即我对它的结果不感兴趣,并且希望调用线程在异步方法完成之前继续。

这样做的正确方法是什么?我在 .NET Framework 4.6 和 .NETCore 2 中都需要这个,以防有差异。

public async Task<MyResult> DoWorkAsync(){...}

public void StarterA(){
    Task.Run(() => DoWorkAsync());
}

public void StarterB(){
    Task.Run(async () => await DoWorkAsync());
}

Run Code Online (Sandbox Code Playgroud)

它是这两者之一还是不同/更好的东西?

//编辑:理想情况下没有任何额外的库。

Ste*_*ary 5

这样做的正确方法是什么?

首先,您需要确定您是否真的想要即发即忘。根据我的经验,大约 90% 提出此要求的人实际上并不想要一劳永逸;他们想要一个后台处理服务。

具体来说,即发即忘意味着:

  1. 您不在乎操作何时完成。
  2. 您不在乎执行操作时是否有任何异常。
  3. 如果动作完成你不在乎在所有

因此,“即发即忘”的实际用例非常小。像更新服务器端缓存这样的操作就可以了。发送电子邮件,生成的文件,或任何相关业务是正常的,因为你会(1)要完成的动作,和(2)得到,如果该操作有一个错误通知。

绝大多数情况下,人们根本不想要一劳永逸;他们想要一个后台处理服务。构建其中之一的正确方法是添加一个可靠的队列(例如,Azure 队列 / Amazon SQS,甚至是一个数据库),并拥有一个独立的后台进程(例如,Azure Function / Amazon Lambda / .NET Core BackgroundService / Win32服务)处理该队列。这本质上是 Hangfire 提供的(使用队列的数据库,并在 ASP.NET 进程中运行后台进程)。

它是这两者之一还是不同/更好的东西?

在一般情况下,省略async和时存在许多小的行为差异await。这不是您“默认”想做的事情。

但是,在这种特定情况下 - asynclambda 只调用一个方法 - 省略async并且await很好。