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语句中有三个线程!是什么赋予了?
笔记:
更新
这是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)不用于同步 - 它是在执行某些操作(即启动时)后阻止数据库操作一段时间的.它大部分时间都是设置的.将其从锁定块中取出也无法解决问题.