gpt4 book ai didi

c# - BackgroundWorker 取消

转载 作者:行者123 更新时间:2023-11-30 20:46:22 30 4
gpt4 key购买 nike

我在我的 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

最佳答案

如果您能更具体地说明您不愿意传递 BackgroundWorker 实例,那将会很有帮助。了解为什么这是一项设计要求有助于更好地回答您的问题。

也就是说,您可以应用与 ProgressChanged 事件相同的理念,并委托(delegate)取消检查。例如:

class GenerateStats
{
public event EventHandler<CancelEventArgs> CheckCancel;

private bool OnCheckCancel()
{
EventHandler<CancelEventArgs> handler = CheckCancel;

if (handler != null)
{
CancelEventArgs e = new CancelEventArgs();

handler(this, e);

return e.Cancel;
}

return false;
}

public void generateForSubject()
{
//Perform db operation not important, but it takes time

OnProgressChanged(33, "Finished 1st set of stats");
if (OnCheckCancel())
{
// Or other cancellation logic here
return;
}

//Perform db operation not important, but it takes time

OnProgressChanged(66, "Finished 2nd set of stats");
if (OnCheckCancel())
{
// Or other cancellation logic here
return;
}

//Perform db operation not important, but it takes time

OnProgressChanged(99, "Finished 3rd set of stats");
if (OnCheckCancel())
{
// Or other cancellation logic here
return;
}
}
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;

genStats.ProgressChanged += (s, pe) => worker.ReportProgress(pe.ProgressPercentage, pe.UserState);
genStats.CheckCancel += (sender1, e1) => e1.Cancel = worker.CancellationPending;
genStats.generateForSubject();
}

这允许 GenerateStats 类检查挂起的取消,而无需直接访问 BackgroundWorker 实例,就像 ProgressChanged 事件允许的那样通过 BackgroundWorker 报告进度,而无需直接访问 BackgroundWorker

关于c# - BackgroundWorker 取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27097968/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com