【发布时间】:2021-12-23 23:41:04
【问题描述】:
我在我的 WPF 应用程序中使用 MVVM 模型。我有一个绑定到取消按钮的命令。我有一个启动按钮,可以启动一些后台工作人员。当我单击取消按钮时,我希望所有后台工作人员停止/退出。 当我点击取消按钮时,使用我当前的代码,后台工作人员不会停止并且“StartEngineeringOperation”完成。谁能帮我解决我在这里做错了什么?
当前代码:
对于 EngineeringViewModel.cs:
公共类 EngineeringViewModel{
public EngineeringViewModel()
{
StartEngineering= new DelegateCommand(o =>
{
worker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
if (worker.IsBusy != true) worker.RunWorkerAsync();
worker.DoWork += (s, e) =>
{
StartEngineeringOperation();
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
};
},
k => true);
Cancel = new DelegateCommand(CancelEngineeringOperation);
}
private void StartEngineeringOperation()
{
startAlarmService();
startTrendQualityCheck();
}
private void CancelEngineeringOperation(object param)
{
worker.DoWork += (s, e) =>
{
if (worker.IsBusy)
{
worker.CancelAsync();
e.Cancel = true;
return;
}
};
}
}
我试过这个: 但似乎不起作用:
private void StartEngineeringOperation()
{
startAlarmService();
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
startTrendQualityCheck();
}
【问题讨论】:
-
您不能只是“取消”任意代码。您的
StartEngineeringOperation必须手动检查是否请求取消并(优雅地)停止它正在做的事情。 -
考虑使用async await Asynchronous programming 而不是后台工作人员。还有CancellationToken用于取消多线程操作。
-
Felix 已经指出
BackgroundWorkers已过时,您应该使用Task.Run和async和await -
即使后台工作人员可能已经过时 - 使用带有取消令牌的任务或其他任何东西都不能解决一般问题。
标签: c# wpf multithreading