我有一个数据仓库,为我的应用程序的模型提供持久层。所有的磁盘访问都是异步的,所以我的整个持久层都是用async/await编写的。我的数据仓库允许其他模块订阅数据的变化:
public event EventHandler<Journaling.DataChangeEventArgs> DataChanged;
protected void OnDataChanged(Journaling.Action a)
{
if (DataChanged != null)
{
DataChanged(this, new Journaling.DataChangeEventArgs(a));
}
}
当我告诉仓库删除一个被其他对象引用的对象时,它也会删除这些其他对象。
public async Task<bool> DeleteAsync(Models.BaseModel model)
{
await DeleteDependentModelsAsync(model).ConfigureAwait(false);
if (await connection.DeleteAsync(model).ConfigureAwait(false) != 1)
return false;
else
{
var deleteAction = new Journaling.DeleteAction(model);
OnDataChanged(deleteAction);
return true;
}
}
这个设置在某种程度上起作用,但是当删除引用其他对象的对象时,我遇到了问题。考虑以下例子:
Object X
Object A1: references X
Object A2: references X
Object A3: references X
我有一个记录器模块,订阅数据存储库的更改并将其输出到文件中。记录器有时需要从存储库获取其他数据以使其输出更易读。删除X对象时的日志应该是:
A1 deleted (parent: X, more information contained in X)
A2 deleted (parent: X, more information contained in X)
A3 deleted (parent: X, more information contained in X)
X deleted
问题在于OnDataChange没有等待事件处理程序的执行。因此,在记录器的事件处理程序被调用之前,数据存储库就已经删除了A1-A3和X。但是,事件处理程序必须获取有关X的一些信息,这是不可能的,因为数据存储库已经删除了X。 我需要在OnDataChanged中等待事件处理程序的执行。这样,我就可以确保记录器在下一个对象从存储中删除之前完成其工作。 有人能指点我如何实现吗?我考虑过使用信号量,但这将打破我在数据存储库和日志记录器之间的松耦合关系。
using
,甚至如果他们知道,有时也会忘记。将处理程序的委托返回一个Task
会使任何添加处理程序的人更难以正确地指示完成。他们可能会这样做,但他们需要更多或更少地试图自毁,这就不那么令人担忧了。这确实给触发事件的代码增加了一些工作量,但我认为这种权衡是值得的。 - Servy