使用Async / Await和EntityFramework

时间:2015-12-08 13:27:50

标签: c# entity-framework stored-procedures asynchronous async-await

我必须调用多个消耗时间的存储过程。理想情况下,这些程序必须在同一时间执行,但它会引发很多问题。

以下是简化代码:

private  async void refresh_Controle(object sender, RoutedEventArgs e)
{
    SqlParameter param1 = new SqlParameter("@devicename", DeviceName);
    Task<int> mcResult = GenkaiBase.Database.ExecuteSqlCommandAsync("exec Refresh_McAfee @devicename", param1);
    int Mc = await mcResult;

    SqlParameter param2 = new SqlParameter("@devicename", DeviceName);

    Task<int> dcaiResult = GenkaiBase.Database.ExecuteSqlCommandAsync("exec Refresh_DCAI @devicename", param2);
    int Dc = await dcaiResult;
}

这有两个问题:

  1. 这些程序一个接一个地执行
  2. 如果我多次调用它,我会收到一个SQL Server错误,其中一个程序被选为受害者。
  3. 我尝试在异步方法中使用此代码同时调用这两个过程:

    public async Task<bool> Refresh_Control(string devicename)
    {
        List<Task> Tlist = new List<Task>();
        Console.WriteLine("Launch Refresh");
    
        SqlParameter param1 = new SqlParameter("@devicename", devicename);
    
        Task<int> mcResult =  Genkai_db.Database.ExecuteSqlCommandAsync("exec Refresh_McAfee @devicename", param1);
    
        SqlParameter param2 = new SqlParameter("@devicename", devicename);
    
        Task<int> dcaiResult =  Genkai_db.Database.ExecuteSqlCommandAsync("exec Refresh_DCAI @devicename", param2);
    
        Console.WriteLine("all set");
    
        Tlist.Add(mcResult);
        Tlist.Add(dcaiResult);
    
        await Task.WhenAll(Tlist.ToArray());
        int mc = await mcResult;
        int dc = await dcaiResult;
    
        Console.WriteLine("Finish Refresh" + mc + dc);
        return true;
    }
    

    逻辑适用于发送事物同时但第二个过程抛出错误导致第一个尚未完成。

    由goole翻译错误:

      
        

    EntityFramework.dll中发生了'System.NotSupportedException'类型的异常,但未在用户代码中处理

      
         

    附加信息:在此上下文中启动了第二个操作   在先前的异步操作完成之前。使用   “等待”以确保完成所有异步操作   在此上下文中调用另一个方法之前。没有成员实例   保证是线程安全的。

    那么交易是什么,为什么我不能同时调用多个存储过程而不被SQL Server卡住?

1 个答案:

答案 0 :(得分:6)

<强>更新

我认为此时EF根本不支持这一点,也许这是一个基于this SO answer的重复问题。它无法做到......抱歉。

<强>原始

问题是你试图await两次。当您将它们传递到await Task.WhenAll函数时,它们会并行运行并等待。然后,您将尝试再次等待它们,而不是访问任务实例的.Result

请尝试下面的代码并告诉我它是否有效。

public async Task Refresh_Control(string devicename)
{
    Task<int> mcResult = 
        Genkai_db.Database.ExecuteSqlCommandAsync("exec Refresh_McAfee @devicename", 
            new SqlParameter("@devicename", devicename));
    Task<int> dcaiResult = 
        Genkai_db.Database.ExecuteSqlCommandAsync("exec Refresh_DCAI @devicename", 
            new SqlParameter("@devicename", devicename));

    await Task.WhenAll(mcResult, dcaiResult);

    int mc = mcResult.Result;
    int dc = dcaiResult.Result;

    Console.WriteLine("Finish Refresh :: mc=" + mc + ", dc=" + dc);
}