1

次のように初期化するスレッドがあります。

Utility.Log("1");

myThread = new Thread(new ThreadStart(delegate
{
    Utility.Log("2");

そして残りのスレッドの実行。奇妙なことに、すべてが try/catch でラップされているにもかかわらず、ログ ファイルに 1 しか表示されず (2 はありません)、未処理の System.IO.FileLoadException が発生しています。デリゲートの本体全体を try/catch でラップしようとしましたが、まだその例外が発生しており、イベント ビューアーは、例外の最上位のメソッドがそのメソッドであると言っています。とても奇妙です。

これを追跡する方法、または少なくとも例外を適切にキャッチする方法についてのアイデアはありますか?

4

4 に答える 4

2

FileLoadException はかなり深刻な事故です。スレッドで実行するコードを JIT コンパイラがコンパイルしようとすると発生します。この例外はコードの実行開始前に発生するため、try/catch ペアではキャッチできません。つまり、 try ブロックに入るに爆撃します。これがスレッドであることを考えると、プログラムがデスクトップにクラッシュするのを止めることはできません。あなたが持っている最後のあえぎはAppDomain.UnhandledExceptionです。e.ExceptionObjectのInnerExceptionプロパティは、実際に何がうまくいかないかを教えてくれます。

そうでなければ、この例外は常に簡単に修正できるはずです。これは構成の問題です。JIT コンパイラは、間違ったバージョン番号を持つアセンブリ、または古いバージョンのアセンブリなどを検出します。AppDomain.UnhandledException から診断できない場合、Fuslogvw.exe ツールは、間違ったアセンブリをどのように見つけているかを示すことができます。ソリューションの完全な再構築は、修正の途中である必要があります。

于 2010-10-23T22:53:41.343 に答える
1

スレッド例外イベント ハンドラを追加する必要があります。

application.run の前にハンドラーを追加するだけで、未処理のスレッド例外をすべてキャッチできます。

msdn からのソース:

[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms errors to go through
    // our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

于 2010-10-23T21:33:15.040 に答える
1

コードの一部しか投稿していないため、質問に回答することはまったく不可能です。そこで、一般的なアドバイスです。

スレッドに匿名メソッドを使用しないでください。何か間違ったことをするのは非常に簡単で、スレッドでキャッチされない例外がアプリケーション全体をダウンさせる可能性があります。

public void MyMethod()
{
    _myThread = new Thread(WorkerThread);
    _myThread.Start();
}

public void WorkerThread(object state)
{
    try
    {
      Utility.Log("2");
    }
    catch (Exception e)
    {
       //log error
    }
}
于 2010-10-23T20:22:08.050 に答える
1

元のtry..catchスレッドは、元のスレッドでのみ、新しいスレッドで例外を確実にキャッチしません。

子スレッドで何が起こっているかを知りたい場合は、独自の例外処理を行う必要があります。「デリゲートの本体全体を でラップしようとしました」に従ってこれを実行しようとしたようですが、try/catchその正確性を確認するには、変更されたコードが必要になります。

子スレッドにデバッグすることで、これを絞り込むこともできるはずです。

于 2010-10-23T20:46:10.017 に答える