我在 winforms 应用程序中使用 BackgroundWorker 来执行另一个类中发生的长时间运行的任务(执行数据库操作)。由于所有工作都是在另一个类中完成的,因此取消并不那么简单。我正在使用另一个类中的一个事件(GenerateStats
) 在后台操作完成时更新进度。我想做类似的事情来取消操作。我不能只打电话cancellationPending
在 DoWork 函数中,因为该方法在完成之前永远不会看到它,这违背了目的。我想要取消功能而不需要将BackgroundWorker传递给generateForSubject()
。无论如何,这可以支持取消吗?generateForSubject()
中的方法GenerateStats
班级。这是执行操作的类的实例化:
GenerateStats genStats = new GenerateStats();
这是我的 DoWork 函数,它调用ReportProgress
每当其他类中的事件被调用时。它还调用其他类的方法generateForSubject()
执行操作的。
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
genStats.ProgressChanged += (s, pe) => worker.ReportProgress(pe.ProgressPercentage, pe.UserState);
genStats.generateForSubject();
}
这是应该启动取消并运行的按钮单击事件处理程序CancelAsync()
private void btnStop_Click(object sender, EventArgs e)
{
if (backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync();
}
}
这是我的单独的类,它执行该操作,并创建 ProgressChanged 事件处理程序,以便我的类可以使用进度信息更新表单。如果取消也能实现类似的效果那就太好了。
public event ProgressChangedEventHandler ProgressChanged;
protected virtual void OnProgressChanged(int progress, string message)
{
if (ProgressChanged != null)
{
ProgressChanged(this, new ProgressChangedEventArgs(progress, message));
}
}
public void generateForSubject()
{
//Perform db operation not important, but it takes time
OnProgressChanged(33, "Finished 1st set of stats");
//I hope to check for cancellation here
//Perform db operation not important, but it takes time
OnProgressChanged(66, "Finished 2nd set of stats");
//I hope to check for cancellation here
//Perform db operation not important, but it takes time
OnProgressChanged(99, "Finished 3rd set of stats");
//I hope to check for cancellation here
}
只是为了澄清我的要求是否存在任何不确定性,是否有任何方法可以支持在另一个类中取消我的 backgroundWorker 而不将 backgroundWorker 传递给该方法。如果绝对没有办法而且我必须这样做,那么我会通过backgroundWorker