我在寫一些調度程序,它可以並行執行各種任務。我使用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
它已經設置爲true,我忘了提及我正在使用SQL Server Express。我將檢查MARS是否啓用了Express版本,但應該是... – pietervp
@pietervp是否在任何地方使用顯式交易? (火星在2005年以上的時候應該會很好) –
沒有交易,只是一些簡單的數據欺詐操作。現在我得到一個''xxx.Setting'類型已被映射多次.'。這真的聞起來像EF緩存靜態變量:( – pietervp