17

Visual Studio 用の Xamarin.Android プラグインで作成された monodroid アプリに有効な例外処理を実装しようとしています。

私は2種類の例外を処理しようとしています:

  1. フォアグラウンド (UI) スレッドで
  2. バックグラウンド (スレッドプール) スレッドで

グローバルハンドラーでの両方のケースで、私はしたいです:

  • ロギング - (分析イベントの送信)
  • ユーザー通知 - (アラート)

特定の調査の後、いくつかの回答が見つかりました herehere、およびhere ですが、 AndroidEnvironment.UnhandledExceptionRaiser と AppDomain.UnhandledException 以外は提案されておらず、すべての場合に機能するとは限りません。

両方のハンドラーを使用しようとしている短いサンプルを作成しました。

AppDomain.CurrentDomain.UnhandledException += (s,e)=>
{
    System.Diagnostics.Debug.WriteLine("AppDomain.CurrentDomain.UnhandledException: {0}. IsTerminating: {1}", e.ExceptionObject, e.IsTerminating);
};

AndroidEnvironment.UnhandledExceptionRaiser += (s, e) =>
{
    System.Diagnostics.Debug.WriteLine("AndroidEnvironment.UnhandledExceptionRaiser: {0}. IsTerminating: {1}", e.Exception, e.Handled);
    e.Handled = true;
};

そして、ボタンをクリックすると、次のコードを追加して、両方のタイプの例外を発生させました。

//foreground exception
throw new NullReferenceException("test nre from ui thread.");
//background exception
ThreadPool.QueueUserWorkItem(unused =>
{
    throw new NullReferenceException("test nre from back thread.");
});

その結果、両方のタイプの例外に対して異なる動作が発生します。

  1. 前景:
    • 両方のハンドラーが発生します
    • アプリがクラッシュするのを防ぐことは不可能です - いずれにしてもクラッシュします (e.Handled = true は単に無視されます)
  2. バックグラウンド:
    • 2 番目のハンドラーのみが発生します
    • アプリがクラッシュしない

私の場合、すべてのユーザー アクション、特にバックグラウンド タスクを try-catch でラップすることはできませんでした。エラーが発生した場合に中断する必要があるビジネスログインがあり、それはまさに実行時に期待するものです。同時に、これらの例外をトップ レベルで 1 か所で処理し、(ビジネス ルールに基づいて) ログに記録し、アプリの実行を続行したいと考えています。

両方の例外を処理し、アプリを存続させる (クラッシュを防ぐ) 方法。

ここで完全なコード サンプルを見つけることができます: https://dl.dropboxusercontent.com/u/19503836/UnhandledException.zip

アドバイスありがとうございます。どんな助けでも感謝します。ティア!

4

2 に答える 2

3

@ Daveoc64 - キャッチされていない例外のグローバルな処理は悪い考えだと強調したあなた (および他の人) には同意しません。UI アプリケーションには必要だと思います。メソッドレベルでの適切な例外処理を否定するものではありません (つまり、強調したようにコンテキストが非常に重要な特定の例外を処理および回復できる場所) - しかし、例外が発生したときに、それに加えて使用されることがあります。アプリケーションの回復はありません。したがって、回復できない例外をキャッチするために try / catch をコードに入れることは無意味です-その catch ブロック内に何を入れても、同じ種類の回復不能なエラーのために他のすべての catch ブロック内にコピーして入れる必要があります-つまり、ユーザーにプロンプ​​トを表示し、正常に終了します。

于 2015-06-30T14:12:42.707 に答える