WPF和后台工作人员
本文关键字:工作人员 后台 WPF | 更新日期: 2023-09-27 18:14:55
我有一个WPF窗口,我想在后台线程做一些工作。
当工作完成后,我想再做一遍。比如在 之间有UI更新的循环我代码:private void InitializeBackgroundWorker()
{
m_stopCamera = false;
m_worker = new BackgroundWorker();
m_worker.DoWork += new DoWorkEventHandler(worker_DoWork);
m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
m_worker.WorkerSupportsCancellation = true;
}
unsafe void worker_DoWork(object sender, DoWorkEventArgs e)
{
// my work....
e.Result = new MyResultClass(p1,p2..);
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
return;
if (e.Error != null)
{
Logger.LogException(e.Error.ToString());
Window_Closed(this, new EventArgs());
}
try
{
//UI work..
DetectionResult result = e.Result as DetectionResult;
if (result.Cancel == true)
{
m_DetectedObjID = result.DetectionID;
// PlaySound();
audio_MediaEnded(this, new EventArgs());
}
else
((BackgroundWorker)sender).RunWorkerAsync();
}
catch (Exception ex)
{
Logger.LogException(ex.ToString());
Window_Closed(this,new EventArgs());
}
}
我知道这段代码不是很好,因为我有一个线程地狱,不能正确调试它
例如. .当代码运行时,我单击关闭按钮,我可以在事件中看到这个工人一直很忙。导致无限循环…
private void Window_Closed(object sender, EventArgs e)
{
if (m_worker.IsBusy)
m_worker.CancelAsync();
while(m_worker.IsBusy);
base.Close();
}
}
我做错了什么?由于
我知道你从来没有在worker_DoWork
中将你的工作标记为已取消。该方法中的取消代码应该如下所示:
if ((m_worker.CancellationPending == true))
{
e.Cancel = true;
return;
}
只有在完成处理程序之后,你才会得到e.Cancelled==true
,循环将停止。
如果你认为调用CancelAsync()
应该设置取消为真,你错了。下面是BackgroundWorker.CancelAsync():
public void CancelAsync()
{
if (!this.WorkerSupportsCancellation)
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntSupportCancellation"));
this.cancellationPending = true;
}
您可以看到,它只是将CancellationPending
设置为true,仅此而已。因此,您必须在worker_DoWork
中检查此属性,如第一个代码片段所示。
clear line:
while(m_worker.IsBusy);//may be go to infinite loop
如果你想在后台运行一些东西,你可以使用这个:
public void DoEvents()
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
code;
DoEvents();
}));
}
代码将在CPU空闲时执行,所以它不会影响主线程的性能。