我在SO上發現了類似的線程,但似乎沒有解決我的確切問題。從多線程調用LINQ-to-SQL中的SubmitChanges()
基本上我使用.NET任務並行庫編寫了一個簡單的生產者/消費者應用程序。生產者在30秒間隔內檢查數據庫表中的記錄。當它找到記錄時,它將它們添加到BlockingQueue
。同時,我使用Task.Factory
對記錄執行一些操作。
當即將對記錄執行操作時,我想更新記錄上的一個字段以指示它已經在隊列中。這是因爲如果生產者在最後一批仍在處理中時檢查新記錄,它不會將舊條目添加回隊列。
我遇到的這個問題是在多線程的數據上下文中調用SubmitChanges()
。我認爲我正在運行競賽條件,但我不確定。
我得到的錯誤是The operation cannot be performed during a call to SubmitChanges.
監製代碼:
BlockingCollection<QueuedMessage> workItems = new BlockingCollection<QueuedMessage>();
System.Threading.Timer workItemTimer = new System.Threading.Timer((s) =>
{
var items = repository.GetQueuedMessages();
foreach (var item in items)
{
workItems.Add(item);
}
}, null, 0, 30000);
消費者代碼:
while (workItems.TryTake(out queuedMessage, Timeout.Infinite, new CancellationToken()))
{
Task.Factory.StartNew((t) =>
{
var messageToSend = (QueuedMessage)t;
repository.MarkQueuedMessageAsProcessing(messageToSend.Id);
...
Do some stuff with messageToSend
....
}, queuedMessage);
}
庫代碼:
var entity = DataContext.QueuedMessages.SingleOrDefault(m => m.Id == messageId);
entity.ProcessingStarted = true;
DataContext.SubmitChanges();
當我跑這與幾個排隊的消息,DataContext.SubmitChanges()
將開始拋出異常,與我前面提到的消息,The operation cannot be performed during a call to SubmitChanges.
就像我說的,我覺得這是因爲我叫它來自多個線程,但我不知道如何解決此問題。
我試圖改變有問題的行:
ThreadPool.QueueUserWorkItem(s => DataContext.SubmitChanges());
但結果都是一樣的。
您的DataContext跨線程共享嗎?如果是這樣,這絕對是你的問題。 – Josh 2012-07-18 19:13:02
嘗試爲存儲庫代碼中的每個更新創建新的數據上下文。 Datacontexts僅適用於單個工作單元 – sga101 2012-07-18 19:13:46