2

我在寫一些調度程序,它可以並行執行各種任務。我使用MEF作爲IoC遏制器。因爲我知道共享一個ObjectContext的靜態實例不是一個好主意,所以我決定每個線程都有一個實例。我是這樣實現的:使用MEF的多線程EF

[Export(typeof(IDatabaseFactory))] 
[PartCreationPolicy(CreationPolicy.Shared)] 
public class DatabaseFactory : IDatabaseFactory 
{ 
    [Import] 
    public IServiceResolver ServiceResolver { get; set; } 

    [ThreadStatic] 
    private static IEntityModel _dataContext; 

    public IEntityModel Get() 
    { 
     if (_dataContext == null) 
     { 
      Debug.WriteLine("*************************"); 
      Debug.WriteLine(string.Format("Created Context Instance on Thread {0}", Thread.CurrentThread.ManagedThreadId)); 
      Debug.WriteLine("*************************"); 
     } 

     return _dataContext ?? (_dataContext = ServiceResolver.GetService<IEntityModel>()); 
    } 

    public void Dispose() 
    { 
     Debug.WriteLine("^^^^^^^^Disposing Context^^^^^^^^"); 

     if (_dataContext != null) 
     { 
      _dataContext.Dispose(); 
      _dataContext = null; 
     } 
    } 
} 

注意_dataContext字段上的ThreadStatic屬性;此代碼失敗,並輸出如下:

************************* 
Created Context Instance on Thread 9 
************************* 
-- Running Main Thread on thread 9 
-- Scheduling servicetask of type ActiveDirectorySynchronisationServiceTask on thread 14 
-- Scheduling servicetask of type LogCleanerServiceTask on thread 15 
-- Scheduling servicetask of type TranscriptParseServiceTask on thread 17 
-- Scheduling servicetask of type MailServiceTask on thread 16 
************************* 
************************* 
Created Context Instance on Thread 15 
************************* 
Created Context Instance on Thread 17 
************************* 
Created Context Instance on Thread 16 
************************* 
************************* 

有了以下的ErrorMessage:

{"The transaction operation cannot be performed because there are pending requests working on this transaction."} 

需要注意的是實際的錯誤並不總是相同的,(有時「基礎提供失敗的開放」,等等),它說服我這是一個多線程問題。但我沒有看到問題?

是ObjectContext的實例之間共享的連接嗎?我使用EF4.0,SQL Server Express的2008

回答

0

你需要MARS(多個活動結果集),http://msdn.microsoft.com/en-us/library/h32h3abf(v=vs.80).aspx

EF試圖共享連接SQL如果可能的話,這需要在連接啓用上述功能字符串級別。只有在同時激活多個活動環境(多線程應用程序或關閉不良的環境)時,纔會真正看到此問題。

+0

它已經設置爲true,我忘了提及我正在使用SQL Server Express。我將檢查MARS是否啓用了Express版本,但應該是... – pietervp

+0

@pietervp是否在任何地方使用顯式交易? (火星在2005年以上的時候應該會很好) –

+0

沒有交易,只是一些簡單的數據欺詐操作。現在我得到一個''xxx.Setting'類型已被映射多次.'。這真的聞起來像EF緩存靜態變量:( – pietervp

0

我找到了解決此問題的解決方案。我在ObjectContext類定義中添加了一個[PartCreationPolicy(CreationPolicy.NonShared)]。可能是因爲沒有明確定義此屬性而使用共享引用。