6

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

下面是简化代码:

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; 
} 

这有2个问题:

  1. 这些程序等
  2. 如果我叫其再次,我得到一个SQL后执行一个服务器错误,其中一个过程被选为受害者。

我打过电话在同一时间两个程序使用此代码在异步方法:

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; 
} 

的逻辑是罚款,送东西的同时,但第二个过程抛出一个错误导致第一个尚未完成。

错误由古尔翻译:

“System.NotSupportedException”类型的异常出现在EntityFramework.dll但在用户代码

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

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

+1

实体框架,你不能,你可以有多个方面,但我想你可以用正常的ADO.NET – brykneval

回答

5

更新

我认为,这根本就不是由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); 
} 
+0

做到这一点它提高比我在行第二为例相同的错误开始任务 dcaiResult =。 (看到主要帖子中的错误)。一个CMD已经启动,我必须等待,然后执行一个后续一个? – Zwan

+0

await不运行任务,它等待已经运行的任务。当时Task.WhenAll是hin两个任务已经在运行。 – usr

+0

是的,并且错误不在等待执行第二个过程的行上。它的ether EF或SQL服务器拒绝exec。但我怀疑它没有解决这个问题。 – Zwan

相关问题