【发布时间】:2015-01-21 18:14:05
【问题描述】:
我在我的 winforms 应用程序中使用 BackgroundWorker 来执行另一个类中发生的长时间运行的任务(执行数据库操作)。由于所有工作都在另一个类中完成,因此取消并不那么简单。我正在使用另一个类 (GenerateStats) 中的事件来更新后台操作完成时的进度。我想通过取消操作来做类似的事情。我不能只在 DoWork 函数中调用cancellationPending,因为该方法在完成之前永远不会看到它,这违背了目的。我想要取消功能,而无需将 BackgroundWorker 传递给generateForSubject()。无论如何,这可以支持从GenerateStats 类中的generateForSubject() 方法取消。这是操作在其中执行的类的实例化:
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
【问题讨论】:
标签: c# winforms backgroundworker cancellation