锁定语句似乎不起作用

Cil*_*lan 5 c# multithreading locking

我有这个方法:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我从多个线程调用它(调用相同的实例),但在TableProperty.Single上抛出异常(Sequence不包含任何元素).在调试代码时,我看到在另一个线程检查了缓存是否存在之后,正在创建一个从数据库中删除项目的情况.除非lock语句中有多个线程(syncroot对象绝对是跨线程的相同实例),否则这是不可能的.

不可能?我有证据: 不可能的情况

lock语句中有三个线程!是什么赋予了?

笔记:

  1. MRE已设置(不阻塞).
  2. 这不是抛出异常的情况,它只是在锁定部分中显示多个线程.更新:我将图像更改为异常的intellitrace事件.旧图像在这里
  3. syncroot对象不是静态的,因为我只想调用同步的同一个实例.

更新

这是syncroot对象的声明:

private object syncroot = new object();
Run Code Online (Sandbox Code Playgroud)

还有一些其他声明:

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

我不能使syncroot静态,因为我有几个类运行的实例,重要的是它们不会相互阻塞.但这并不重要 - 让它静止并不能解决问题.

ManualResetEvent(waitForContextMRE)不用于同步 - 它是在执行某些操作(即启动时)后阻止数据库操作一段时间的.它大部分时间都是设置的.将其从锁定块中取出也无法解决问题.

Cil*_*lan 0

我已经调试这个问题有一段时间了,虽然我还没有解决它,但我很清楚锁正在工作。我猜测问题出在 DataContext (众所周知,它在多线程情况下很棘手)。