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

相關問題