在我的应用程序中,我有一个主窗口并进入它,在一个框架中我加载页面。当用户按下按钮时,该页面执行很长时间的任务。我的问题是,当长任务正在进行并且用户按下主窗口的关闭按钮时,应用程序似乎没有完成,因为我在VS2008中调试它,我可以看到突出显示停止按钮。如果我想完成,我必须按停止按钮,应用程序不会在应用程序退出时自动停止调试。我认为.NET在应用程序退出时会自动停止后台工作人员,但在看到此行为后我不确定。我试图在卸载的事件页面中强制并取消后台工作程序,如下所示:
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
// Is the Background Worker do some work?
if (My_BgWorker != null && My_BgWorker.IsBusy)
{
//If it supports cancellation, Cancel It
if (My_BgWorker.WorkerSupportsCancellation)
{
// Tell the Background Worker to stop working.
My_BgWorker.CancelAsync();
}
}
}
但没有成功。在做了CancelAsync()之后,几分钟之后,我可以看到后台工作完成并引发RunWorkerCompleted我可以看到任务已完成检查事件中的e.Cancelled参数但是在此事件被激活之后应用程序继续而没有退出并且我有不知道在做什么......
我将WorkerSupportsCancellation设置为true以支持在开始时取消。
我会答应所有的答案。感谢。
答案 0 :(得分:4)
取消不是自动的,DoWork
事件处理程序中的代码需要通过检查CancellationPending
属性的值来处理取消。调用CancelAsync
不会中止该线程,它只会将CancellationPending
设置为true ...
例如:
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
while(!bgw.CancellationPending)
{
...
}
}
答案 1 :(得分:0)
我认为Thomas Levesque指出了这个问题。
总的来说:在某个地方,某个线程仍在执行。您可以通过暂停调试过程(暂停按钮,名为“Break All”)来尝试找出什么线程。此时,应突出显示执行的下一个代码行。此外,您可以使用“线程”窗口(在“调试” - >“Windows”下)查看哪个线程仍在运行,以及在哪里。
答案 2 :(得分:-1)
Perfect Thomas,将ShutdownMode设置为OnMainWindowClose就像你说的那样解决了我的问题。现在调试器正确停止;)非常感谢帮助我。
我做的是:
<Application
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:Class="GParts.App"
StartupUri="WinMain.xaml"
ShutdownMode="OnMainWindowClose">
<...>
</Application>
最后,我想对DoWork事件中的backgroundworker做一件事情,以防某些类型的错误抛出异常:我用try catch子句来处理它里面的错误,然后抓住catch:
catch (Exception ex)
{
e.Result = ex.Message;
}
当backgroundworker完成异常时,我想在RunWorkerCompleted中使用e.Error检测它并显示它。所以我在RunWorkerCompleted中做的是:
if (e.Cancelled)
{
// Cancelled
}
else if (e.Error != null)
{
// Exception Thrown
// Here I want to show the message that produced the exception in DoWork
// event. If I set e.Result = ex.Message in DoWork event, is e.Error here
// containing ex.Message?
}
else
{
// Completed);
}
RunWorkerCompleted中的e.Error是否包含ex.Message?
感谢。