如何在c#优化中取消具有多个方法的后台工作者
本文关键字:方法 工作者 后台 优化 取消 | 更新日期: 2023-09-27 18:01:24
我有一个后台工作人员与几个不同的函数和循环。我在网上找到的每一个例子都只有一个循环和一个函数。现在我想知道是否存在一个简短的解决方案来取消一个按钮的工人。我只知道两个我认为不是最优的解决方案。
1:在每个函数/循环中添加if/else ->长而容易混淆的代码
loop
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
do calculation
}
}
2:像这样用abort杀死backgroundworker线程(如何完全"杀死"backgroundworker ?)
我希望计算在点击取消按钮后立即停止,无论当前执行哪个循环或函数。还有比我的机会更好的吗?
编辑:我不知道为什么我怎么能取消一个任务没有循环应该解决我的问题,因为我有许多不同的循环
在使用后台worker时,实际上唯一的选择就是在代码中添加检查,以查看操作是否已被取消。
如何实现这个完全取决于你,但我想说你想在每个可能耗时的操作开始时检查,例如数据库查询或文件系统操作,以及在每个循环开始时。
现在,正如您已经注意到的,当涉及到多个方法时,它变得更加棘手。在这种情况下,将worker存储在类级别字段中可能是合适的,这样您就可以简单地从每个方法中检查它的取消状态。
一个有用的方法是利用您自己的自定义Exception类。你可以将代码封装在try-catch块中的顶层方法中,然后无论何时你发现后台工作线程在调用堆栈的某个更深的地方被取消,你都可以抛出一个异常实例,它将由catch块处理。这是我做的一个简单的例子。
class CancellationException : Exception
{
public object State { get; private set; }
public CancellationException(object state)
{
this.State = state;
}
}
private void DoSomething()
{
if (_worker.CancellationPending)
{
throw new CancellationException("cancelled from blah blah");
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
DoSomething();
}
catch (CancellationException ce)
{
e.Cancel = true;
}
}
请注意,异常中的State
属性可用于确定进程中取消发生的位置,以便您可以清理资源等。