2013-07-25 3 views
7

は、私が観測されない例外を無視するように、これを行うために使用される:それは良い習慣であるかどうかMonoTouchでasync/awaitで観測されない例外を無視する方法は? MonoTouchでの以前のバージョンで

TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e) { 
    Console.WriteLine (e); 
    e.SetObserved(); 
}; 

は議論の余地があるが、私はasync/awaitキーワードと同じ効果を達成するために知りたいですnow officially supported in Xamarin.iOS 6.4。私はそれを実行すると、AsyncVoidMethodBuilderでデバッガを一時停止

async void OnClick (object sender, EventArgs e) 
{ 
    await Task.Run (() => { throw new Exception(); }); 
} 

:ここ

は、私がテストに使用コードです

enter image description here

私は.NET 4.5おそらくchanged the behaviour so unobserved exceptions don't crash the appこのブタを読みます例外がUIKit同期コンテキストに送信され、それらを処理できない場合は役に立ちません。

MonoTouchのawaitの観測されない例外を無視する方法はありますか?

+1

「AsyncVoidMethodBuilder」で「一時停止」しています。これは、継続してヒットした場合、例外は最終的にハンドラによって飲み込まれることを意味しますか?これは、この例外でデバッガだけが停止するケースですか?また、あなたが参照した記事には、.NETのような例外処理を行うためのapp.config設定がいくつか含まれています。 –

+0

@ブラッド:私が続行すると、プロセスがクラッシュします。その理由は、基本的なUIKitSynchronizationContextによってUIスレッドで例外が再スローされるからです。設定は、動作が*より厳しくなるように設定されているので、助けにはならないはずです。あなたは有効なポイントを立てました。以前のバージョンでは、UIスレッドにスローされたにもかかわらず、Unobservedハンドラで例外をキャッチすることができました。 –

+1

タスク、AppDomainなどのさまざまな監視されていないハンドラがあります。UI固有のハンドラを使用してみてください。 SynchronizationContextで例外を返すことをお待ちしております。 –

答えて

7

これはasync void方法の正しい動作です:彼らはasync void方法が起動時にアクティブであったSynchronizationContextに例外を発生させるをを想定しています。

.NET 4.5で言及した変更は、観察されていないタスクの例外のみを処理しており、async voidのメソッドには適用されません。

(Microsoft).NETの世界では、異なるSynchronizationContext実装では、トップレベルのエラー処理が異なります。 WPF、WinForms、およびASP.NETはすべて、通常、Applicationタイプの一部としてそのエラーを処理するさまざまな方法を持っています。

MonoのUIKit APIを見ましたが、私は普通のMonoユーザーではありませんでしたが、UIApplicationでトップレベルのエラー処理が見つかりませんでした。UIKitSynchronizationContextは公開されていない(または少なくとも文書化されていない)ようです。

この問題を見て別の方法に:async voidメソッドの例外処理動作は、(詳細は、my MSDN articleを参照)を持っているのと同じようなイベントハンドラになるように設計されています。だからあなたは別の質問で質問に答えることができます:UIKitでは、この例外をどのように扱いますか?

void OnClick (object sender, EventArgs e) 
{ 
    throw new Exception(); 
} 

あなたはasync voidの例外をまったく同じ方法で処理します。あなたがUnobservedTaskExceptionを使用して保存しておきたい場合は

あるいは、あなたは、単にタスク例外を観察することはできません(自分のasync voidコードでは、Task.Runは、例外を取得するタスクを返し、あなたはawaitを使用して、それを観察している):

void OnClick (object sender, EventArgs e) 
{ 
    Task.Run(() => { throw new Exception(); }); 
} 

ただし、イベントハンドラにはasync voidを使用し、すべてのタスクを(最終的に)awaitにすることをお勧めします。これにより、プログラムが正しく動作しなくなり、その理由がわからない "サイレントエラー"(タスクの例外は無視されます)が発生しなくなります。

+0

ありがとうございます。私はそれを待ってタスクの例外を観察していることに気づいていませんでした。今、私がUIKit例外を処理する方法を知っていれば、 –

+1

Dan、これらのUIKit例外を監視する方法はありますか? –

+1

こんにちはダン、同じ質問、あなたはUIKitの例外を処理するために管理していますか? – Fabien