2

在我的应用程序中,我有一个主窗口,并在其中加载一个页面。当用户按下按钮时,此页面会执行很长时间的任务。我的问题是,当正在执行长任务并且用户按下主窗口的关闭按钮时,应用程序似乎没有完成,因为我正在 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() 后,几分钟后,我可以看到 backgroundworker 完成并引发 RunWorkerCompleted 并且我可以看到任务已完成检查事件中的 e.Cancelled 参数,但是在执行此事件后,应用程序继续而不退出,我有不知道在做什么......

我将 WorkerSupportsCancellation 设置为 true 以在开始时支持取消。

我会感谢所有答案。谢谢。

4

3 回答 3

4

取消不是自动的,DoWork事件处理程序中的代码需要通过检查CancellationPending属性的值来处理取消。调用CancelAsync不会中止线程,它只是设置CancellationPending为真......

例如 :

private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
    while(!bgw.CancellationPending)
    {
        ...
    }
}
于 2010-03-26T13:15:44.603 回答
0

我认为 Thomas Levesque 指出了这个问题。

一般来说:某处,一些线程仍在执行。您可以通过暂停调试过程(暂停按钮,名为“Break All”)尝试找出线程是什么。此时,应突出显示下一个执行的代码行。此外,您可以使用“线程”窗口(在 Debug -> Windows 下)准确查看仍在运行的线程以及在何处运行。

于 2010-03-26T13:22:30.267 回答
-1

完美的托马斯,如您所说,将 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;               
        }

当后台工作人员因异常完成时,我希望在 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?

谢谢。

于 2010-03-29T07:11:05.740 回答