我有一个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();
}
}
我做错了什么?感谢
答案 0 :(得分:1)
明确界限:
while(m_worker.IsBusy);//may be go to infinite loop
答案 1 :(得分:1)
AFAIK你永远不会在worker_DoWork
中将你的作品标记为已取消。该方法中的取消代码应如下所示:
if ((m_worker.CancellationPending == true))
{
e.Cancel = true;
return;
}
只有在那之后你才会在完成处理程序中获得e.Cancelled==true
并且你的循环将停止。
如果您认为调用CancelAsync()
应将Canceled设置为true,那么您就错了。这是来自BackgroundWorker.CancelAsync()的反编译代码:
public void CancelAsync()
{
if (!this.WorkerSupportsCancellation)
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerDoesntSupportCancellation"));
this.cancellationPending = true;
}
正如您所看到的,它只是将CancellationPending
设置为true,仅此而已。因此,您必须在worker_DoWork
中检查此属性,如第一个代码段所示。
答案 2 :(得分:0)
如果您想在后台运行某些内容,可以使用:
public void DoEvents()
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
code;
DoEvents();
}));
}
代码将在CPU空闲时执行,因此不会影响主线程的性能。