1

私はリアクティブフレームワークから始めています..例に基づいて:

http://rxwiki.wikidot.com/101samples (ピンポン)

私は自分のアプリケーションで同様の実装を行いました..アクションをOnErrorに渡す方法がわかりませんでした(クラス外でアクセスされ、ISubject実装)

どのようにできるのか?

public class PFocusPing : ISubject<PFocusPong, PFocusPing>
{
    private readonly AdvancedConnection device;
    public PFocusPing(AdvancedConnection con)
    {
        this.device = con;
    }

    #region Implementation of IObserver<PFocusPong>
    public void OnNext(PFocusPong value)
    {
        this.device.SendData(clsPowerFocus.DataKeepAlive);
        Console.WriteLine("PFocusPing received PFocusPong.");
    }

    public void OnError(Exception exception)
    {
        Console.WriteLine("PFocusPing experienced an exception and had to quit playing.");
    }

    public void OnCompleted()
    {
        Console.WriteLine("PFocusPing finished.");
    }
    #endregion

    #region Implementation of IObservable<PFocusPing>
    public IDisposable Subscribe(IObserver<PFocusPing> observer)
    {
        return Observable.FromEventPattern<Args<DataReceive>>(add => device.DataReceived += add,
                                                     rem => device.DataReceived -= rem)
                                                    .Where(obj => obj.EventArgs.Value.Result == DataReceive.CONNECTION_RESULT.SUCESS)
                                                    .Where(obj => obj.EventArgs != null &&
                                                                  obj.EventArgs.Value != null &&
                                                                  obj.EventArgs.Value.Data != null &&
                                                                  obj.EventArgs.Value.Data.Length > 0)
                                                    .Select(obj => this)
                                                    .Subscribe(observer);

    }
    #endregion

    #region Implementation of IDisposable
    public void Dispose()
    {
        OnCompleted();
    }
    #endregion
 }

public class PFocusPong : ISubject<PFocusPing, PFocusPong>
{
    private readonly int timeout;
    private readonly int reply;
    private DateTime lastAnswer;

    public PFocusPong(int msPing, int msTimeout)
    {
        this.reply = Math.Max(1000, msPing);
        this.timeout = Math.Max(2000, msTimeout);
    }

    #region Implementation of IObserver<Ping>

    public void OnNext(PFocusPing value)
    {
        this.lastAnswer = DateTime.Now;
        Console.WriteLine("PFocusPong received Ping.");
    }

    public void OnError(Exception exception)
    {
        Console.WriteLine("PFocusPong experienced an exception and had to quit playing.");
    }

    public void OnCompleted()
    {
        Console.WriteLine("PFocusPong finished.");
    }

    #endregion

    #region Implementation of IObservable<PFocusPong>

    public IDisposable Subscribe(IObserver<PFocusPong> observer)
    {
        var keepAlive =
            Observable.Timer(TimeSpan.FromMilliseconds(0), TimeSpan.FromMilliseconds(reply))
            .Select(obj =>
                {
                    if ((DateTime.Now - this.lastAnswer).TotalMilliseconds < reply)
                    {
                        Console.WriteLine("True");
                        return true;
                    }

                    Console.WriteLine("False");
                    return false;
                });

        var keepDead = keepAlive.Where(obj => obj).Timeout(TimeSpan.FromMilliseconds(timeout)).Subscribe(r =>
            {
                if (!r)
                    throw new TimeoutException();
            });


        var disposable = keepAlive.Finally(keepDead.Dispose).Select(n => this).Subscribe(observer);
        return disposable;
    }

    #endregion

    #region Implementation of IDisposable

    public void Dispose()
    {
        OnCompleted();
    }

    #endregion

}
4

1 に答える 1

1

あなたの質問が何であるかわかりません。ただし、混乱は出発点から生じる場合があります。ISubject<T1, T2>ISubject<T>IObserver<T>またはIObservable<T>インターフェースを実装しないことを強くお勧めし ます。

拡張メソッドを使用して監視可能なシーケンス ( )Subscribe(Action<T>, Action<Exception>, Action)をサブスクライブし、ファクトリ メソッドまたはその他の変換メソッド (たとえば、FromEvent、ToObservable など)を使用する必要があります。IObservable<T>Observable.Create

また、ピンポンは Rx の精神とはまったく異なります。Rx とは、一連のイベントを観察して構成することです。Ping-Pong は、メッセージ パッシングのように見えます。Rx は通常、一方向のものです。つまり、キーボード イベントをリッスンして何かを実行したり、気温の変化や新しい価格などをリッスンしたりします...

通常、イベントを取得したときにキーを押し戻すことはありません。

于 2013-04-25T18:56:08.283 に答える