1

アプリケーションにローダーを実装しようとしていWPFます。いくつかの重い操作中に UI スレッドがフリーズするため、スレッドを使用してローダーを実装する必要がありました。ローダーがロードされるたびに、新しいスレッドが作成され、ローダーがオフになると、このスレッドは (手動で) 中止されます。私が直面している問題は、時々アプリケーションがクラッシュしてThreadAbortException.

これは、ローダーを開始するコードです。

try
        {
            //if(newWindowThread !=null && !newWindowThread.IsAlive) { }
            newWindowThread = new Thread(new ThreadStart(() =>
            {
                try
                {
                    // Create and show the Window
                    awq = new BusyIndicatorDisguise(BusyMessage);
                    awq.Show(); // <== POINT WHERE THE EXCEPTION IS THROWN
                    //Start the Dispatcher Processing
                    if (!isDispatcherStarted)
                    {
                        var a = Thread.CurrentThread;
                        var b = Dispatcher.CurrentDispatcher;
                        //isDispatcherStarted = true;
                        Dispatcher.Run();
                    }

                }
                catch (ThreadAbortException thEx)
                {

                }
                catch (Exception ex)
                {

                }
            }
            ));
            // Set the apartment state
            newWindowThread.SetApartmentState(ApartmentState.STA);
            // Make the thread a background thread
            newWindowThread.IsBackground = true;
            // Start the thread
            newWindowThread.Start();
        }
        catch (Exception ex)
        {

        }

このコードはローダーを停止するためのものです:

if (newWindowThread != null && newWindowThread.IsAlive)
        {          
            newWindowThread.Abort();              
        }

catch ブロックでこの例外をキャッチできません。別スレにあるからかな。ThreadAbortException を回避する方法を知りたい

4

2 に答える 2

1

スレッドに try catch ブロックを追加して、例外をスローし、必要に応じて管理する必要があります。

とにかく、@ Joshが他の同様の投稿で言っているように

Thread.Abort を使用せずにスレッドを中止するはるかに優れた方法があります。これは、予測できない時点でコードを無秩序に中断するだけでなく、スレッドが現在アンマネージ コードを呼び出している場合、スレッドが中止されないため、動作が保証されません。コントロールがマネージ コードに戻るまで。

aManualResetEvent などの何らかのタイプの同期プリミティブを使用して、スレッドにいつ終了するかを伝えるフラグとして機能する方がはるかに優れています。この目的のためにブール値フィールドを使用することもできます。これは、BackgroundWorker が行うことです。

于 2016-04-22T05:22:02.007 に答える
1

自分で例外をスローする場合は、Thread.Abort. それが理由です:

  • 例外のスローは、非常にコストのかかる操作です。コール スタック全体とその他の有用なデータをデバッグ用に保存します。この場合、単純なフラグを設定するだけで済みます。
  • ThreadAbortExceptionトリッキーなものです。Thread.ResetAbortブロック内で呼び出さない限り、例外ハンドラ ブロックの最後で自動的に再スローされますcatch。しかし、そうしないでください
  • AThreadAbortExceptionは非同期例外であり、コードのどの時点でも発生する可能性があり、予測できない結果を引き起こす可能性があります。End taskこれは、タスク マネージャーのボタンなどのブルート フォース ツールです。実行されたコード (サード パーティ コンポーネント) を書き換えることができず、不安定な実行環境の残りをアンロードできることが確実な場合にのみ使用してください (実行されますAppDomain)。

bool代わりに、ロード操作中に定期的にポーリングする必要があるローダーにキャンセル要求を送信します (単純な の場合もあります)。以下BackgroundWorkerは、および volatile フィールドを使用してそれを行う方法の例です。

于 2016-04-22T06:08:53.137 に答える