3

Reactive Framework を簡単に導入できるプログラムです。しかし、プログラムを次のように変更して、エラーハンドラーを試してみたいと思います。

var cookiePieces = Observable.Range(1, 10);
cookiePieces.Subscribe(x =>
   {
      Console.WriteLine("{0}! {0} pieces of cookie!", x);
      throw new Exception();  // newly added by myself
   },
      ex => Console.WriteLine("the exception message..."),
      () => Console.WriteLine("Ah! Ah! Ah! Ah!"));
Console.ReadLine();

このサンプルでは、​​次のオーバーロードが使用されています。

public static IDisposable Subscribe<TSource>(
     this IObservable<TSource> source, 
     Action<TSource> onNext, 
     Action<Exception> onError, 
     Action onCompleted);

例外メッセージが表示されることを期待しましたが、コンソール アプリケーションがクラッシュしました。理由は何ですか?

4

3 に答える 3

5

例外ハンドラーは、オブザーバーではなく、オブザーバブル自体で作成された例外に使用されます。

例外ハンドラを起動する簡単な方法は次のようなものです:

using System;
using System.Linq;

class Test
{
    static void Main(string[] args)
    {
        var xs = Observable.Range(1, 10)
                           .Select(x => 10 / (5 - x));

        xs.Subscribe(x => Console.WriteLine("Received {0}", x),
                     ex => Console.WriteLine("Bang! {0}", ex),
                     () => Console.WriteLine("Done"));

        Console.WriteLine("App ending normally");
    }
}

出力:

Received 2
Received 3
Received 5
Received 10
Bang! System.DivideByZeroException: Attempted to divide by zero.
   at Test.<Main>b__0(Int32 x)
   at System.Linq.Observable.<>c__DisplayClass35a`2.<>c__DisplayClass35c.<Select
>b__359(TSource x)
App ending normally
于 2010-07-13T09:54:00.297 に答える
3

Rx ライブラリでは、IObservable (Select、Where、GroupBy など) で機能するオペレーターに渡されるすべてのユーザー コードがキャッチされ、オブザーバブルにサブスクライブされたオブザーバーの OnError ハンドラーに送信されます。これらが処理される理由は、それらが計算の一部であるためです。

Observer コードで発生する例外は、ユーザーが処理する必要があります。これらは計算の最後にあるため、Rx がこれらをどのように処理するかは不明です。

于 2010-07-13T17:12:54.597 に答える
0

本当にクラッシュしたり、Visual Studio にジャンプしたりして、例外が発生したことを示していますか? 2 番目が当てはまる場合は、メニュー バー内の [デバッグ - 例外] を調べて、右側のすべての選択を解除する必要があります。

于 2010-07-13T10:04:28.847 に答える