[英]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语句中有三个线程! 是什么赋予了?
笔记:
更新资料
这是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.