MVVMにおいてVMで非同期は必要か?async void/Taskのどちらが良いか?非同期処理の例外ハンドリングは?

C# MVPを始めとした方々がガチ議論!(誰でも編集可なので抜け等あればご自由に)
9
前へ 1 ・・ 3 4 6 次へ
尾上 雅則 @ugaya40

@masaru_b_cl 業務例外なら、アプリケーション落とさずに表示するんでしょうから、そういうサービスに飛ばすなりイベント出すなりじゃないですかね。想定"外"なやつは、集約エラーハンドラでロギングして落としますよね

2014-12-11 17:19:58
neuecc @neuecc

例外伝搬という話に絞れば、voidの時は誰が処理していたのか。例外は強制的に伝搬されるものだから、今までエンジンが処理してたと思ってる(そうじゃなきゃ完全にクラッシュする)。じゃあasyncなら?やはり同様にエンジンが処理すべきだと思うし、そのためにはTaskである必要がある。

2014-12-11 17:21:07
白い高野さん @masaru_b_cl

@ugaya40 さっきの例はアレですが、業務例外はMがハンドリングして、何らかの方法で上に通知するっていう考えということですね。

2014-12-11 17:22:49
neuecc @neuecc

voidなら例外は伝搬され検知できる。非同期ならエンジンがawaitしなければならない、そのためにはTaskである必要がある。

2014-12-11 17:22:52
尾上 雅則 @ugaya40

@neuecc いあModelの一番表側のメソッドの話ではそこがasyncな理由は中でawaitしてるからであって、awaitの後にContinueWith以外のコードが続くこともないし虚空に消える例外は発生しないっていう前提があります。

2014-12-11 17:25:45
Ktz @ktz_alias

@masaru_b_cl Promise (パターン?)分かると、基本挙動は割と何とかなる

2014-12-11 17:27:03
尾上 雅則 @ugaya40

asyncがついているからそのメソッドは虚空に消える非同期な例外を出してくるというわけではない。中でawaitしてそれに対する例外処理を記述して、非同期な例外はそのメソッド内で発生可能性が閉じていても、それでもそのメソッドの頭にasyncが必要で、そういうのが混乱の元感ある

2014-12-11 17:27:41
白い高野さん @masaru_b_cl

@ktz_alias PromiseとかFurtureとかActorとかRxとか、非同期周りは大変です……

2014-12-11 17:28:05
neuecc @neuecc

@ugaya40 その前提は恐らくおけないんじゃないでしょうか?不意に発生する例外は存在しうるかと(そうでなければ全てをtry-catchで囲むことが強要されるけど、これは非現実的では)

2014-12-11 17:28:37
neuecc @neuecc

@ugaya40 つまりさっき私が書いた全てをtry-catchで囲むことが強要されるパターン、でしょうか?

2014-12-11 17:47:41
尾上 雅則 @ugaya40

@neuecc いあ、一番表のメソッドは囲んでないです。内側の奴は今回はtry~catchしてますけど、ContWithでもいいです。

2014-12-11 17:48:33
尾上 雅則 @ugaya40

@neuecc 伝わりにくいので書き換えます

2014-12-11 17:49:01
尾上 雅則 @ugaya40

@neuecc ちょっとわからなくなってきたんですが、try~catchにOnlyOnFaultedに比べてパフォーマンス的な問題があるならそもそもasync/await使用しなきゃ良いのではないでしょうか?awaitだと例外をコントロールしたいタイミングでtry~catch

2014-12-11 18:54:06
尾上 雅則 @ugaya40

@neuecc 以外やりようないという認識なんです。awaitでも呼び出し元でOnlyOnFaultedを使う方法あるんでしょうか?

2014-12-11 18:54:35
neuecc @neuecc

@ugaya40 んー、try-catchでもOnlyOnFaultedでも一緒かとは。Testメソッドはtry-catch(でもOnlyOnFaulted)しなければならないのか、しない場合はどうなるのか、ってとこです。

2014-12-11 19:14:50
neuecc @neuecc

UnobservedTaskExceptionはダメ。発生タイミングがGC時なので、その前に取れなければならない。ASP.NETだったらApplication_Error、WPFだったらDispatcherUnhandledException。

2014-12-11 19:18:02
neuecc @neuecc

async voidの問題は2点。一つは例外が虚空に消えてUnobservedTaskExceptionでしか捉えられないことがあること。その点において、Forms/WPFはDispatcherUnhandledExceptionに行くので問題ない。

2014-12-11 19:18:22
neuecc @neuecc

一方、ASP.NETはダメ(この違いはSynchronizationContextがWPFはアプリの生存期間中生き続けるのに比べ、ASP.NETはリクエスト単位なのですぐ消滅するところにある)

2014-12-11 19:18:48
neuecc @neuecc

もう一つは、集約例外でしか例外を捉えられないこと、完了を確認できないこと。これはアプリケーション内部だけなら問題ないが、DLLとして別の形で叩いてみたり、ユニットテスト時に障害になる(その点がvoidとasync voidが根本的に異なるところ)

2014-12-11 19:20:19
neuecc @neuecc

async Taskには受け側に選択権がある。FireAndForgetしたければすればいいし(そうすればasync voidと同じ)、Waitで同期的に待機してもいい。あえてそうした選択権を破棄したい理由があるかどうか(イベントにはある、なぜならvoidでしか受けれないから)

2014-12-11 19:22:00
尾上 雅則 @ugaya40

@neuecc Testメソッドはtrycatchする必要がないという認識で始めています。なので受け手にはそもそも選択肢がないです

2014-12-11 19:23:19
前へ 1 ・・ 3 4 6 次へ