現在許多Web項目都使用了IOC的DI注入組件。其中對象的生命周期管理是非常重要的。
有時我們為了提高請求的響應,經常在請求線程中執行多個子線程,然而忽略了EF的DbContext的生命周期管理。
DbContext並非是線程安全的。子線程A和子線程B 可能同時的對同一個DbContext進行操作,從而導致下面的異常(可能隨機拋出其中一個)。
所以建議不要不同線程共用同一個DbContext.
{"已有打開的與此 Command 相關聯的 DataReader,必須首先將它關閉。"}
“System.InvalidOperationException”類型的異常在 EntityFramework.dll 中發生,但未在用戶代碼中進行處理 其他信息: The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.
“System.NullReferenceException”類型的異常在 EntityFramework.dll 中發生,但未在用戶代碼中進行處理
其他信息: 未將對象引用設置到對象的實例。
“System.InvalidOperationException”類型的異常在 System.Data.dll 中發生,但未在用戶代碼中進行處理
其他信息: 不允許更改“ConnectionString”屬性。連接的當前狀態為已關閉。
測試代碼
1 private async void button1_Click(object sender, EventArgs e) 2 { 3 try 4 { 5 var mydb = new MyDbContext(); 6 var arr = new MyExecuterOfEF[2]; 7 arr[1] = new MyExecuterOfEF(mydb, (db) => 8 { 9 var r = db.Tests.FirstOrDefault(); 10 }); 11 arr[0] = new MyExecuterOfEF(mydb, (db) => 12 { 13 var r = db.Tests.FirstOrDefault(); 14 }); 15 16 Parallel.ForEach(arr, (myExecute) => 17 { 18 myExecute.Execute(); 19 }); 20 21 MessageBox.Show("結束"); 22 } 23 catch (Exception ex) 24 { 25 //MessageBox.Show(ex.ToString()); 26 this.textBox1.Text = ex.ToString(); 27 } 28 }
