【问题标题】:Parallelize without Task.Run()没有 Task.Run() 的并行化
【发布时间】:2018-07-20 20:13:34
【问题描述】:

是否可以在不使用 Task.Run() 产生新线程的情况下让某些东西在后台运行(例如数据库查询)?

数据库查询示例

public async Task Query(long objectToDelete)
{
    using ( var ctx= new Context())
    {
        Car car = new Car { Id = objectToDelete};

        ctx.Entry(employer).State = EntityState.Deleted;

        await ctx.SaveChangesAsync();
    }
}

据我了解,查询是同步运行的,直到第一个“等待”,然后控制权返回给调用者,

我想知道我是否可以留下这样的来电者:

public async Task Caller( long id)
{
    var runningQuery = Query( id);

    /* do something else

    */

    // await runningQuery; // commented out so "Caller" can complete early
}

【问题讨论】:

  • 请指定您喜欢的项目,如 Windows 窗体、Web api、控制台或任何其他
  • 这是一个 ASP.NET 项目,所以查询在 GET 中
  • @UberFace - 当您在问题的“奇迹”部分尝试代码时发生了什么?
  • 只要“做其他事情”不依赖于runningQuery 中的Task 的结果,或者它可能做出的任何状态更改,这是完全可以接受的。

标签: c# multithreading entity-framework async-await


【解决方案1】:

您完全可以做到这一点。只要SaveChangesAsync 返回,查询就会运行。 await 暂停执行,直到任务完成。所以不要使用 await (你做对了)。

请注意,“一劳永逸”的工作非常困难。您需要确保记录错误。此外,您通常不能依靠工作来完成。可能存在错误(如网络中断、死锁或超时),或者您的整个进程可能在查询完成之前退出。这在 ASP.NET 中尤其重要。如果您在任何时候都不等待,可以考虑选择“火而忘记工作”。

【讨论】:

    【解决方案2】:

    await 关键字将在它被调用的方法内停止执行并将执行返回到调用该方法的方法。所以如果你想早点从“来电者”返回,你只需离开

    await runningQuery;
    

    到位。

    这个微软Page 解释了它。如果您查看标题 What Happens in an Async Method 下的图表,您将获得逻辑流程的良好视觉参考。

    【讨论】:

      猜你喜欢
      • 2019-02-24
      • 1970-01-01
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 2015-09-28
      • 2020-09-10
      • 2021-06-21
      • 2018-07-03
      相关资源
      最近更新 更多