使用Action

时间:2019-04-25 21:04:34

标签: c# multithreading .net-core

我在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方法退出之前强制其运行? 如果不是这种情况,那会是什么?

0 个答案:

没有答案