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はスレッドを中止せず、CancellationPendingtrue に設定するだけです...

例えば ​​:

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

Thomas Levesque が問題を特定したと思います。

一般的なメモ: どこかで、いくつかのスレッドがまだ実行中です。デバッグ プロセスを一時停止することで、それがどのスレッドであるかを調べてみることができます (「Break All」という名前の一時停止ボタン)。この時点で、次に実行されるコード行が強調表示されます。また、[スレッド] ウィンドウ ([デバッグ] -> [ウィンドウ] の下) を使用して、実行中のスレッドとその場所を正確に確認できます。

于 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 に関して 1 つのことを行いたいと思います。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 が含まれていますか?

ありがとう。

于 2010-03-29T07:11:05.740 に答える