我有一些构建用户响应类的函数,我仍在掌握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;
});
}
答案 0 :(得分:1)
如何按照现在设置的方式进行通话?
它将工作安排到后台线程(Task.Run
),然后异步等待它完成(await
)。该工作将一次执行一个数据库proc,同步阻塞后台线程直到它完成。
如何并行运行所有这些调用?
您可以使用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(我在博客中描述的原因) - 使用自然异步方法会更好。