以正确的顺序触发异步/等待功能中的事件

眼睛

我在确保异步任务中事件的顺序方面遇到问题。从其继承其他异步任务的类具有以下功能,并在构造函数参数中采用EventHandlers(ExecutionProgress,ExecutionStarted,ExecutionCompleted)

public abstract Task Operation(IProgress<EventArgs> progress);

public virtual void Execute()
{
    ExecuteAsync()
}

private void ReportProgress(EventArgs args)
{
    if(ExecutionProgress != null) ExecutionProgress(this, args);
}
private async Task ExecuteAsync()
{
    if(ExecutionStarted != null) ExecutionStarted(this, EventArgs.Empty)
    await Operation(new Progress<EventArgs>(ReportProgress));
    if(ExecutionCompleted != null) ExecutionCompleted(this, EventArgs.Empty)

}

现在在我的一个继承自异步任务的类中,我用以下内容覆盖了Operation:

public override async Task Operation(IProgress<EventArgs> progress)
{
    // run the synchronous function in another thread
    JobResults results = await Task.Run(() => worker.DoYourJob()); 
    progress.Report(results);
}

尝试访问JobResults,经常(但并非总是)运行此代码会ExecutionCompleted事件处理程序中导致NullReference Exception这是因为无论出于何种原因,写入成员变量的ExecutionProgress事件通常都会在ExecutionCompleted之后触发我认为该标准没有说明事件排序,但是我正在寻找一个很好的解决方案来确保确定性排序。我只想在处理完所有ExecutionProgress事件后才触发ExecutionCompleted。

这里有什么好看的解决方案?在处理所有进度报告事件之前,有什么方法可以等待

务实的

所有事件均按顺序触发如果您的事件处理程序是异步的(似乎是这种情况),那么触发事件的代码将在启动事件处理程序后立即继续执行,而不是在它们完成继续执行

如果触发事件的代码无需在所有处理程序都完成之前继续进行,那么您需要重新构造此类,以便事件处理程序可以在完成时向此类指示某种方式。有任何数量的方式来做到这一点,从传递参数,使处理程序告诉它处理完成后的情况下,或者具有事件处理程序的签名返回Task,而不是void(你需要await那些触发事件时的任务)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章