【问题标题】:How to run multiple call with-in a function parallel如何在函数中并行运行多个调用
【发布时间】:2016-06-20 22:18:30
【问题描述】:

我有一些构建用户响应类的函数,但我仍在掌握 TASK 异步等待。

从下面的代码中,有没有一种方法可以并行运行所有这些,而不是一次运行一个?

我想我的第一个问题应该是现在的通话是如何进行的?

我的第二个问题是如何并行运行所有这些调用?

退货无需按任何特定顺序退货

public static async Task<ProjectForDrawings> GetProjectInfo(string cnn, int projectID)
    {

        return await Task.Run(() =>
        {
            ProjectForDrawings projectForDrawings = DataBase.proc_GetProject_ForDrawings.ToRecord<ProjectForDrawings>(cnn, projectID);

            projectForDrawings.Submittals = DataBase.proc_GetSubmittal.ToList(cnn, projectID);

            projectForDrawings.ProjectLeafs = DataBase.proc_GetProjectLeafs.ToList<ProjectLeaf>(cnn, projectID);

            projectForDrawings.Revisions = DataBase.proc_GetRevisionsForProject.ToList<Revisions>(cnn, projectID);

            return projectForDrawings;
        });
    }

【问题讨论】:

    标签: c# .net async-await


    【解决方案1】:

    现在通话是如何进行的?

    它将工作安排到后台线程 (Task.Run),然后异步等待它完成 (await)。该工作将一次执行一个数据库过程,同步阻塞后台线程,直到完成。

    如何并行运行所有这些调用?

    你可以启动所有的任务,然后await他们都用Task.WhenAll

    public static async Task<ProjectForDrawings> GetProjectInfo(string cnn, int projectID)
    {
      ProjectForDrawings projectForDrawings = DataBase.proc_GetProject_ForDrawings.ToRecord<ProjectForDrawings>(cnn, projectID);
    
      var submittalsTask = Task.Run(() => DataBase.proc_GetSubmittal.ToList(cnn, projectID));
      var leafsTask = Task.Run(() => DataBase.proc_GetProjectLeafs.ToList<ProjectLeaf>(cnn, projectID));
      var revisionsTask = Task.Run(() => DataBase.proc_GetRevisionsForProject.ToList<Revisions>(cnn, projectID));
    
      await Task.WhenAll(submittalsTask, leafsTask, revisionsTask);
    
      projectForDrawings.Submittals = await submittalsTask;
      projectForDrawings.ProjectLeafs = await leafsTask;
      projectForDrawings.Revisions = await revisionsTask;
      return projectForDrawings;
    }
    

    但是,许多(大多数?)数据库不允许每个数据库连接进行多次查询,因此这可能不适用于您的数据库。此外,首先并行化对数据库的调用可能不是一个好主意 - 可能会导致自我强加的拒绝服务。最后,using Task.Run in the implementation is not a good pattern(出于我在博客中描述的原因)——使用自然异步方法会更好。

    【讨论】:

    • 在这篇文章中说明 2005 年及更高版本的 sql server 有一个连接池,如果调用者在同一连接上调用 db,它将获取一个可用连接并用它。如果没有打开的连接,它将向调用者抛出一堆可用的连接以供选择。这里只是闲聊,我理解正确吗?
    • @AlumCloud.Com:这取决于DataBase 方法的实现方式。如果他们都使用独立的DbConnection,那应该可以。如果他们都使用相同的 DbConnection 实例,那么您将看到一个异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多