我在Debian 9 x64上的.NET Core 2.2控制台应用程序中运行以下C#代码:
DbCall(Action action) {
try {
lock(thisLock) {
action();
}
}
catch (Exception ex) {
//exception handling
}
}
private T DbCall<T>(Func<T> func) {
try {
lock(thisLock) {
return func();
}
} catch (Exception ex) {
//exception handling
}
}
public void RemoveClassAEntity(ClassA classAentity) {
DbCall(() => {
DbContext.ClassAEntities.Remove(classAentity);
DbContext.SaveChanges();
});
}
public List<ClassA> GetClassAEntities(Func<ClassA, bool> condition) {
return DbCall(() => {
return DbContext.ClassAEntities
.Where(condition)
.ToList();
});
}
public void RemoveClassAEntitiesWithCondition() {
var entities = GetClassAEntities(e => SatisfiesCondition(e));
entities.Sort();
entities.ForEach(e => RemoveClassAEntity(e));
}
有许多类似于RemoveClassAEntity的方法,这就是为什么我引入了DbCall方法的原因,所以我不需要重复进行锁定和异常处理。 方法RemoveClassAEntity是公共的,可以从多个线程中调用。但是,不能同时从同一实体的不同线程中调用它(SatisfiesCondition不能在不同线程中同时返回true)
我的问题是“值不能为空。参数名称:实体”有时会发生错误,该错误源于“ action();”行。我相当确定,永远不会使用null参数调用RemoveClassAEntity。我只能通过在生产环境中检查错误日志来重现调试器的问题。
我希望传递给DbCall的委托与调用方法同步执行,但是给人的印象是委托在调用方法退出后执行,这就是发生异常的原因。如果是这种情况,如何在RemoveClassAEntity方法退出之前强制其运行? 如果不是这种情况,那会是什么?