Rx Нужна помощь в написании иерархии для классов - PullRequest
0 голосов
/ 25 августа 2010

Я использовал 101 образец Rx Framework (http://rxwiki.wikidot.com/101samples#toc47) в последнем примере и создал класс, как показано ниже, и использование, как в тестовой функции.


private void Test()
{
    var order = new Order();
    order.ObservableOrder.Subscribe(
        ord => Console.WriteLine("Order progress "),  // subscribe to onnext event
        ex => Console.WriteLine("Paid error " + ex.Message),   // subscribe to error event
        () => Console.WriteLine("Paid oncompleted ")  // subscribe to completed event
      ); // Subscribe

     order.Start();
 }


 public class Order
 {
      private readonly Subject<Order> _subject = new Subject<Order>();
      public IObservable<Order> ObservableOrder { get { return _subject.AsObservable(); } }

      public void RaiseError() {
         _subject.OnError(new Exception("test exception"));
      }
      public void RaiseCompleted() {
          _subject.OnCompleted();
      }
      public void RaiseProgress() {
          _subject.OnNext(this);
      }

      public void Start() {
             for (int i = 0; i < 5; i++)
                   this.RaiseProgress();

              this.RaiseError(); // either error is raised 
              this.RaiseCompleted();  // or completed is raised
      }
    } 

Мое требование заключается в том, какнаписать базовый класс (или какую-то фабрику), чтобы упростить его использование для 20-30 классов, выполняющих аналогичные действия (например, они должны отправлять данные о прогрессе, незавершенных событиях и ошибках). Как я также могу отправить некоторые данные?вернуться к выполнению и завершенным событиям (например, мы отправляем исключение в событие onerror)

1 Ответ

0 голосов
/ 26 августа 2010

OnCompleted() не принимает аргументов, которые, очевидно, не могут быть изменены.

У вас есть несколько вариантов:

Вы можете создать класс полезной нагрузки, в котором будут и процесс, и конечная полезная нагрузка. class OrderProgress { double Process; OrderResult Result; }

Вы можете выставить другую тему, Progress, на которую вы можете подписаться в дополнение к ObservableOrder.

Если вы хотите оставить Start реентерабельным, вы можете заставить его вернуть объект, который выставляет как Progress, так и OrderProgress наблюдаемые.

Редактировать: Включая пример кода (моего второго варианта):

private void Test() 
{ 
    var order = new Order(); 

    order.ObservableProgress.Subscribe( 
        prog => Console.WriteLine("Order progress " + prog.ToString()
    );

    order.ObservableOrder.Subscribe( 
        ord => Console.WriteLine("Order progress"),
        ex => Console.WriteLine("Paid error " + ex.Message), 
        () => Console.WriteLine("Paid oncompleted")
    );

    order.Start(); 
}


public class Order 
{ 
    private readonly Subject<Order> _subject = new Subject<Order>(); 
    private readonly Subject<double> _progressSubject = new Subject<double>(); 

    public IObservable<Order> ObservableOrder
    {
        get { return _subject.AsObservable(); }
    }

    public IObservable<double> ObservableProgress
    {
        get { return _progressSubject.AsObservable(); }
    }

    public void RaiseError() { 
        _subject.OnError(new Exception("test exception")); 
    } 

    public void RaiseCompleted() {
        _subject.OnNext(this); 
        _subject.OnCompleted(); 

        _progressSubject.OnCompleted();
    } 

    public void RaiseProgress(double progress) { 
        _progressSubject.OnNext(progress); 
    } 

    public void Start() { 
        for (int i = 0; i < 5; i++) 
            this.RaiseProgress((double)i / 5D); 

        this.RaiseError(); // either error is raised  
        this.RaiseCompleted();  // or completed is raised 
    } 
}  
...