在 backgroundworker 中取消长 运行 进程的最佳方法
Best way to cancel long running process inside backgroundworker
快速取消后台工作程序中较长 运行 进程的最佳解决方案是什么?
比如我们有这样的情况:
private void DoWork(object sender, DoWorkEventArgs e)
{
...
for (int i = 0; i < items; i++)
{
if (_worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
VeryLongRunningProcess();
}
}
}
private void VeryLongRunningProcess()
{
var a = Test();
var b = Test2();
Thread.Sleep(5000);
var c = Test3();
}
在这种情况下,VeryLongRunningProcess() 将不会在按下取消时完成,直到他完成体内的所有内容。
遇到这种情况怎么办?
我试图将 (BackgroundWorker)sender 作为参数传递给 VeryLongRunningProcess() 并在此方法中检查 CancellationPending,但我不知道这种方法是否正确
通常您应该创建 long-running 进程作为“异步”方法(public 异步任务或任务 DoWork())以用于资源分配目的。 “CancelationToken”启用线程、线程池工作项之间的协作取消。也可以传播一个回调委托,当取消令牌取消或函数完成时可以调用它。
如果问题与 worker 一样与 类 隔离了 VeryLongRunningProcess,您可以使用 Func 作为参数并在方法之外保留 worker 访问权限
private void VeryLongRunningProcess(Func<bool> isCancelled)
{
var a = Test();
if (isCancelled())
{
return;
}
var b = Test2();
if (isCancelled())
{
return;
}
Thread.Sleep(5000);
var c = Test3();
}
在您的方法中,您可以根据需要多次检查是否必须取消操作。您可以将 Func 用作其他方法(如 Test1、Test2...)中的参数,如果它们中的任何一个需要很长时间才能完成。
然后,您以这种形式调用您的方法:
VeryLongRunningProcess(() => _worker.CancellationPending);
正如其他人评论的那样,使用 async/await 可能很有趣。
更新
另一种选择是否使用取消的方法:
private void VeryLongRunningProcess(Func<bool> isCancelled = null)
{
var a = Test();
// Or: isCancelled != null && isCancelled()
if (isCancelled?.Invoke() ?? false)
{
return;
}
// ...
}
快速取消后台工作程序中较长 运行 进程的最佳解决方案是什么? 比如我们有这样的情况:
private void DoWork(object sender, DoWorkEventArgs e)
{
...
for (int i = 0; i < items; i++)
{
if (_worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
VeryLongRunningProcess();
}
}
}
private void VeryLongRunningProcess()
{
var a = Test();
var b = Test2();
Thread.Sleep(5000);
var c = Test3();
}
在这种情况下,VeryLongRunningProcess() 将不会在按下取消时完成,直到他完成体内的所有内容。
遇到这种情况怎么办?
我试图将 (BackgroundWorker)sender 作为参数传递给 VeryLongRunningProcess() 并在此方法中检查 CancellationPending,但我不知道这种方法是否正确
通常您应该创建 long-running 进程作为“异步”方法(public 异步任务或任务 DoWork())以用于资源分配目的。 “CancelationToken”启用线程、线程池工作项之间的协作取消。也可以传播一个回调委托,当取消令牌取消或函数完成时可以调用它。
如果问题与 worker 一样与 类 隔离了 VeryLongRunningProcess,您可以使用 Func 作为参数并在方法之外保留 worker 访问权限
private void VeryLongRunningProcess(Func<bool> isCancelled)
{
var a = Test();
if (isCancelled())
{
return;
}
var b = Test2();
if (isCancelled())
{
return;
}
Thread.Sleep(5000);
var c = Test3();
}
在您的方法中,您可以根据需要多次检查是否必须取消操作。您可以将 Func 用作其他方法(如 Test1、Test2...)中的参数,如果它们中的任何一个需要很长时间才能完成。
然后,您以这种形式调用您的方法:
VeryLongRunningProcess(() => _worker.CancellationPending);
正如其他人评论的那样,使用 async/await 可能很有趣。
更新
另一种选择是否使用取消的方法:
private void VeryLongRunningProcess(Func<bool> isCancelled = null)
{
var a = Test();
// Or: isCancelled != null && isCancelled()
if (isCancelled?.Invoke() ?? false)
{
return;
}
// ...
}