在 backgroundworker
中进行长时间运行的测量。由于 SRP
( Single reponsibility principle ),测量应该不知道它正在另一个线程中运行。
让我们考虑这个例子:
void MeasurementWorker(object sender, DoWorkEventArgs e)
{
Measurement measurement = new Measurement();
measurement.Execute();
}
如何允许取消这种模式的测量?
编辑:Measurement.Execute
现在是长期运行的测量方法,它应该是可以取消的,但它应该不会违反线程上下文测量的 SRP
。例如,在没有线程上下文的情况下进行一些测试。
如果您希望您的测量处理是可取消的,您必须让它知道某种取消标志。另一种方法是以不合规的方式取消(中止)它,但这是非常不鼓励的,因为您可能会在重要的事情中间停止处理,而不给它清理或释放资源的机会。
您可以使用 Task Parallel Library 而不是 BackgroundWorker
然后代码可能如下所示:
CancellationTokenSource cts = new CancellationTokenSource();
Task tsk = Task.Factory.StartNew(() =>
{
Measurement measurement = new Measurement();
measurement.Execute(cts.Token);
},
cts.Token,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
Execute
可能看起来像这样:
public void Execute(CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
while (true)
{
// processing
// ...
// need to cancel?
ct.ThrowIfCancellationRequested();
}
}
要在主线程中取消调用:
cts.Cancel();
您将得到 TaskCancelledException
但这是预期的。
或者,如果您不希望出现异常,请使用以下版本的Execute
。它不严格符合 TPL 准则,但如果您不使用条件 continuations,它会正常工作.
public void Execute(CancellationToken ct)
{
if (ct.IsCancellationRequested)
return;
while (true)
{
// processing
if (ct.IsCancellationRequested)
return;
}
}
我是一名优秀的程序员,十分优秀!