【问题标题】:FireAndForget implementation with Task [duplicate]使用 Task 实现 FireAndForget [重复]
【发布时间】:2019-09-18 10:56:06
【问题描述】:

我有一个异步方法 DoSomething(),在 DoSomething() 内部我调用了另一个方法“SaveINSQLDB()”,如下所示。

private static async Task Dosomething()
{
    my few lines of code....

    SaveINSQLDB()... // I don't want wait for its response to execute further
                     // (fire and forget case).
    my few lines of code
}

我可以使用以下任何一种方法,请向我推荐最佳的方法(并请说明原因?)。

案例一。

Task.Run(() => SaveINSQLDB(arg1, arg2)); 

我可以使 SaveINSQLDB() 成为一个简单的静态方法。

案例2。

await Task.Run(async () =>
                          {
                             await SaveINSQLDB(arg1, arg2);
                          }); 

我可以将 SaveINSQLDB() 设为静态异步方法。

在我看来,Case1 更好。

【问题讨论】:

  • 为什么你认为Case1 更好?它们可能都以相同的方式编译到 IL。
  • 案例 2.await Task.Run(async () => { await SaveINSQLDB(arg1, arg2); }); 嗯,案例 2 正在等待结果,所以它不会被忽略
  • @Selvin case 1 甚至不会触发。你仍然需要运行task.Wait() 或其他东西。否则,它只是包装到 Task
  • 案例一是正确的解决方案,触发一个新任务但不要等待它的结果
  • @Olegl case 1 甚至不会触发。您仍然需要运行 task.Wait() 或其他东西。否则,它只是包装到任务中 are you sure? ...似乎您读了太多“任务不是线程”...在Task.Run的情况下,我们可以说任务是一种线程Task.Run - 将指定的工作排入队列以在 ThreadPool 上运行

标签: c# async-await fire-and-forget


【解决方案1】:

案例 1 将开始 Task 并在之后立即执行 Dosomething() 的其余部分。

案例 2 将启动 Task 并等待它完成,然后再执行 Dosomething() 的其余部分。

因此,如果您想在不阻塞并等待其完成的情况下调用SaveINSQLDB,您应该使用第一个选项。您可能想要捕获异常并在传递给Task.Run 的操作中进行一些日志记录。

【讨论】:

    【解决方案2】:

    如果是我,我会选择案例 1。很明显,在这种情况下就是“一劳永逸”。

    在情况 2 中,await 关键字的存在可能会使阅读它的人认为如果他们将 await 误认为是针对不在即发即弃过程中的顶级调用,那么它将等待响应。

    您不会对等待的回复执行任何操作,因此无需等待。

    编辑:抱歉,我错过了案例 2 中的第一个等待。正如 ​​Selvin 在对我的答案的评论中指出的那样,案例 2 不会触发并忘记,因为它正在等待回复。如果您想要“即发即弃”,则案例 1 是可行的方法。

    MS docs 的示例是否类似于 case1:

    var t = Task.Run(() => {  Console.WriteLine("Task thread ID: {0}",
                                       Thread.CurrentThread.ManagedThreadId);
                                 } );
    

    【讨论】:

    • 在情况 2 中,await 关键字的存在可能会使阅读它的人认为如果他们将 await 误认为是针对不在火中的顶级调用,它将等待响应-然后忘记过程。 什么?有 2 个等待 ...await Task.Run(async () => await ...) 表示它不会像在async Task Dosomething() 内部那样触发和忘记
    • 是的,你是对的,我完全错过了第一次等待,以防万一 2
    猜你喜欢
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 2018-04-27
    • 2012-07-03
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多