5

質問をカバーするトピックがたくさんあります。しかし、それでも私には問題があります。

AppDomain次のように、アセンブリを new にロードします。

public void Run()
{
    //There's the problem.
    //As Panos Rontogiannis mentioned the thread is created in default AppDomain
    new Thread(RunApp).Start();
}

private void RunApp()
    try
    {
        AppDomain.CreateDomain("domain name").ExecuteAssembly("path to assembly");
    }
    catch (Exception _e)
    {
        MessageBox.Show("Unhandled Exception.\n" + _e);
    }
}

読み込まれたアセンブリの Main メソッドで、ハンドラーをUnhandledExceptionイベントにサブスクライブします。

AppDomain.CurrentDomain.UnhandledException += handleException;

ハンドラー自体:

public static void handleException(object a_s, UnhandledExceptionEventArgs a_args)
{
    var _e = (Exception)a_args.ExceptionObject;
    //Static loger class method
    Loger.WriteError(_e.GetType().ToString(), _e.Message, "default solution");
}

ただし、読み込まれたアセンブリで例外がスローされても、ハンドラーは関与しません。AppDomainデフォルト(first )でのみ例外をキャッチしますtry{} catch{}

4

6 に答える 6

4

おそらく、 new で例外を処理できない理由は、AppDomainその で作成されたスレッドから例外がスローされないためですAppDomainAppDomain.UnhandledExceptionに関するドキュメントから、それを確認するのはあまり簡単ではありません。興味深い部分は次のとおりです。

適用可能な例外ハンドラーが見つからずにスレッドのスタック全体がアンワインドされた場合にのみ例外が処理されないため、イベントが発生する最初の場所は、スレッドが発生したアプリケーション ドメインになります。

スローするコードを実行するスレッドがメインAppDomain(コンソール アプリのメイン スレッドなど) に作成されている場合は、 main にハンドラーを追加する必要がありますAppDomain。ただし、スローされた例外のタイプがメインの AppDomain にロードされていない場合、.NET のアセンブリ ローダーはアプリケーションのベース ディレクトリとプローブ パスからそれをロードしようとします。これらが child と同じでない場合AppDomain、アセンブリは解決されず、(その他の) 例外がスローされます。

于 2013-03-26T23:37:39.903 に答える
1

これにはさまざまな理由が考えられます。http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspxのイベント ドキュメントでは、この複雑さのかなりの部分が詳細に説明されています。該当するものがない場合は、再現コードを投稿していただけますか?

于 2013-03-22T12:02:45.883 に答える
0

私の推測では、例外が処理されるため、ハンドラーは呼び出されません。つまり、上位のtry {}catch{}によって。

于 2013-03-22T11:35:20.637 に答える
0
  1. FirstChanceException発火します。
  2. すべてcatchのブロックが実行されます。
  3. ブロックがない場合、catchまたはブロックthrow内にある場合はUnhandledException発火します

あなたのブロックはそれが発火しないcatchことを保証します。UnhandledException

于 2015-06-11T14:05:08.283 に答える
0

これは遅い返信ですが、私に尋ねるとこれはうまくいくようです (VS2012/.NET 4.5)。もちろん、ExecuteAssembly が呼び出される前に例外ハンドラーを登録する必要があります: (書き込みによってアクセス違反を引き起こす子プロセスがあります)クラッシュを強制するためだけにnull参照(安全でないコード)にすると、以下のHandleExceptionがトリガーされます。

public static void HandleException(object a_s, UnhandledExceptionEventArgs a_args)
{
    var _e = (Exception)a_args.ExceptionObject;
    Console.WriteLine(_e.GetType().ToString(), _e.Message, "default solution");
}

public void StarProcessWithinAppDomain(string fileName)
{
    try
    {
        // New appdoamin / check exception isolation level 
        AppDomain sandBox = AppDomain.CreateDomain("sandBox");
        try
        {
            AppDomain.CurrentDomain.UnhandledException += HandleException;
            sandBox.ExecuteAssembly(fileName);
        }
        catch (Exception ex)
        {
            Console.WriteLine("An error occurred (inner) within AppDomain, executing \"{0}\":" + "\n" + ex.Message, fileName);
        }
        finally
        {
            AppDomain.Unload(sandBox); 
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("An error occurred within AppDomain, executing \"{0}\":" + "\n" + ex.Message, fileName);
    }
}
于 2014-05-05T15:02:31.417 に答える