并行任务代码,用于进行多个数据库访问

时间:2014-03-26 06:54:18

标签: c# asynchronous task-parallel-library task

我正在努力加快我的一些代码,

我对慢速数据库进行了2或3次读取,我想让这些调用以并行方式运行。

FSKWebInterfaceEntities dbSrc = new FSKWebInterfaceEntities();

public void main()
{     
 var TaskUsr = GetUserAsync(dev);
 var TaskOldCompany = GetOldCompanyAsync(dev);
 await Task.WhenAll();

 var usr = TaskUsr.Result;
 var oldCompanyName = TaskOldCompany.Result;
 ..... 
 use my two variables to insert a new entry into my localdb
}


    private async Task<ut_User> GetUserAsync(ut_UserAPNdevices dev)
    {
        return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID);
    }

    private async Task<String> GetOldCompanyAsync(ut_UserAPNdevices dev)
    {
        return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID).Company;
    }

在我的两个辅助方法上,它带有绿色下划线并表示没有等待,因此将同步运行。但是我无法返回return await dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID);

我应该如何修改我的代码以使两个并行读取?

2 个答案:

答案 0 :(得分:0)

您可以等待该行,因为它不是异步方法。您无法真正等待数据库调用,因为它们不是线程安全的。有关实现方法的示例,请参阅this主题,并更好地解释原因。您也可以考虑使用具有async methods的SqlCommands。

答案 1 :(得分:0)

您不能同时使用相同的EF DbContext。来自EF小组的statement about thread safety

  

目前,EF将检测开发人员是否尝试执行   一次两个异步操作并抛出。

您仍然可以异步调用它们,但是按顺序调用它们:

public async Task main()
{     
 var sr = await GetUserAsync(dev);
 var oldCompany = await GetOldCompanyAsync(dev);
 ..... 
 use my two variables to insert a new entry into my localdb
}

更新了以解决评论:

  

你能不能发一个我如何改变我的简单例子   上面的代码使用多个dbcontext,因为我真的不知道   正确的方法,我会在黑暗中编码。

如下所示。我不是EF的专家,向您保证这实际上会缩短处理时间。为每个上下文打开数据库连接可能会有很大的开销。

public async Task main()
{     
 var TaskUsr = GetUserAsync(dev);
 var TaskOldCompany = GetOldCompanyAsync(dev);
 await Task.WhenAll(TaskUsr, TaskOldCompany);

 var usr = TaskUsr.Result;
 var oldCompanyName = TaskOldCompany.Result;
 ..... 
 use my two variables to insert a new entry into my localdb
}

private async Task<ut_User> GetUserAsync(ut_UserAPNdevices dev)
{
 using (var dbSrc = new FSKWebInterfaceEntities())
  return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID);
}

private async Task<String> GetOldCompanyAsync(ut_UserAPNdevices dev)
{
 using (var dbSrc = new FSKWebInterfaceEntities())
  return dbSrc.ut_User.FirstOrDefault(x => x.UserID == dev.UserID).Company;
}