簡體   English   中英

鎖定語句似乎不起作用

[英]lock statement does not appear to be working

我有這種方法:

public bool Remove(EntityKeyType key)
{
    lock (syncroot)
    {
        //wait if we need to
        waitForContextMRE.Wait();

        //if the item is not local, assume it is not remote.
        if (!localCache.ContainsKey(key)) return false;

        //build an expression tree
        Expression<Func<EntityType, bool>> keyComparitorExpression = GenerateKeyComparitorExpression(key);

        var itemToDelete = TableProperty.Single(keyComparitorExpression);

        //delete from db
        TableProperty.DeleteOnSubmit(itemToDelete);
        DataContext.SubmitChanges();

        //get the removed item for OnCollectionChanged
        EntityType itemToRemove = localCache[key];
        itemToRemove.PropertyChanged -= item_PropertyChanged;

        //remove from the list
        Debug.Assert(localCache.Remove(key));

        //call the notification
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, itemToRemove));
        return true;
    }
}

我從多個線程調用它(調用相同的實例),但TableProperty.Single始終引發異常(序列不包含任何元素)。 調試代碼后,我看到正在創建一種情況,在另一個線程檢查了高速緩存的存在之后,正在從數據庫中刪除該項目。 除非lock語句中有多個線程,否則這應該是不可能的(syncroot對象在線程之間肯定是相同的實例)。

不可能? 我有證據: 不可能的情況

lock語句中有三個線程! 是什么賦予了?

筆記:

  1. MRE已設置(不阻止)。
  2. 這不是拋出異常的情況,它僅顯示鎖部分中的多個線程。 更新 :我將圖像更改為異常的intellitrace事件。 舊的圖片在這里
  3. syncroot對象不是靜態的,因為我只希望同步調用同一實例。

更新資料

這是syncroot對象的聲明:

private object syncroot = new object();

還有其他一些聲明:

private ManualResetEventSlim waitForContextMRE = new ManualResetEventSlim(true);
private DataContextType _dataContext;
private System.Data.Linq.Table<EntityType> _tableProperty;
//DataContextType and EntityType are generic type parameters

我無法使syncroot保持靜態,因為我有幾個正在運行的類實例,並且它們之間不能互相阻塞很重要。 但這並不重要-將其設置為靜態並不能解決問題。

不存在ManualResetEvent(waitForContextMRE)進行同步-在執行某些操作后(即在啟動時),它會在一段時間內阻止數據庫操作。 大多數情況下設置。 從鎖定塊中取出它也不能解決問題。

我唯一的解釋是waitForContextMRE.Wait(); 調用此命令會使線程取消阻塞syncroot! 因此其他線程可以進入鎖定部分。 嘗試移動waitForContextMRE.Wait(); 在鎖定(...)之前。

我認為您正在調用不同的對象。 屏幕快照上沒有跡象表明您正在從不同線程獲取值。 另外,使用非靜態syncroot也不是一個好主意,因為可能會導致像您這樣的情況。 您是否真的有理由不希望它保持靜態?

我建議鎖定TableProperty或DataContext

我已經調試了一段時間,盡管我沒有解決問題,但我很清楚鎖在起作用 我猜想問題出在DataContext(以在多線程情況下棘手而聞名)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM