0

並行foreach循環我打電話給外部服務做一些對象特定的檢查。 EF似乎完全不喜歡它,並拋出InvalidOperationException異常:「模型創建時無法使用上下文。」在EF#中的並行處理與EF調用

有沒有什麼辦法可以在並行循環中解決這個問題,或者這基本上是我調用非線程安全的環境,永遠不會工作?

我的代碼看起來像這樣:

Parallel.ForEach(users, user => 
{ 
    try 
    { 
     Interlocked.Increment(ref countAll); 
     Console.WriteLine("Task Id {0} processing user: {1}", Task.CurrentId, user.Id); 

     foreach (var item in user.somePropertyList) 
     { 
      var someCheck = _internalService.Method(item.SomeProperty); 

_internal服務使用EF進行檢查

+0

你的代碼是什麼?你能告訴我們一個最簡單的例子,你如何創建/處理你的上下文並運行並行任務? –

回答

0

這個問題可能是您的並行foreach嘗試同時創建多個DataContext S爲第一次。 EF不允許這樣做。

當首次創建EF上下文時,它也將被隱式初始化,即「正在創建模型」。如果併發代碼想要創建另一個上下文,它必須等到第一個上下文成功初始化。

您可以通過提取第一個並行任務來解決這個問題。在沒有任何並行任務的情況下運行這個任務,並在第一個任務完成後開始並行處理

if (!users.Any()) 
    return; 

Process(users.First()) 

Parallel.ForEach(users.Skip(1), user => 
{ 
    Process(user) 
} 

或者,您可以在啓動時運行廉價的虛擬操作,其主要目的是初始化上下文。之後,所有事情都可以並行完成。

_internalService.DoWarmUp(); 

Parallel.ForEach(users, user => 
{ 
    Process(user) 
} 
+0

它不會創建2個'DataContext',它將創建儘可能多的'DataContext',因爲可以創建用於處理數據的線程。這取決於計算機有多少個內核。 – aff

+0

@flechilla,thx。糾正。 –

+0

@Abbondanza,謝謝你的輸入。我正在使用依賴注入,所以我的方法是爲每個用戶創建一個新的服務實例,每次給我新的上下文。我用它爲只讀,所以不要使用EF的UoW方面。它現在工作正常,但我想知道我的方法是不是會相當昂貴? – Bartosz