繁体   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