RX: 1-observable

Source: Internet
Author: User

The. NET ienumerable interface returns ienumerator, while ienumerator implements movenext () and get the current object.

Observable uses this idea to implement push-style using iobservable <t> and iobserver <t>. Our commonly used ienumerble can be understood as PULL mode or active mode, then you need to return ienumerator for the operation. The push mode is the opposite, so iobserver <t> is passed as the iobserverable <t> parameter:

   1:  public interface IObservable<T>
   2:  {
   3:      // Methods
   4:      IDisposable Subscribe(IObserver<T> observer);
   5:  }

   1:  public interface IObserver<T>
   2:  {
   3:      // Methods
   4:      void OnCompleted();
   5:      void OnError(Exception exception);
   6:      void OnNext(T value);
   7:  }

Only the two interfaces are defined in system. observable. dll. This interface is defined in the system namespace.

Inactive and reactive are two ideas. The former is state-based and the latter is event-based. The advantage of event-based notification is that the thread does not need blocking to go to wait, so the program throughput will increase significantly. From another perspective, we can understand that inactive is active, and reactive is passive.

The reactive passive mode is often called the push mode. In this way, iobservable is the "Source" (external thrust) of push, and iobserver is the "target to be pushed ". The two are combined by the subscribe method of the "target". Of course, the "target" can subscribe to multiple "external forces ".

Here is an example of how to add a value from 1 to 100:

   1:  class Program
   2:      {
   3:          /// <summary>
4: // This method directly uses the extension method to create an anonymous observer
   5:          /// </summary>
   6:          /// <param name="args"></param>
   7:          static void Main(string[] args)
   8:          {
   9:              var ob1 = new Ob1();
  10:              ob1.Subscribe(str=>Console.WriteLine(str), ()=>Console.WriteLine("DONE!"));
  11:   
  12:              Console.WriteLine("has subscribed...");
  13:              ThreadPool.QueueUserWorkItem(obj => ob1.DoJob(obj));
  14:              Console.WriteLine("has started DoJob()\n");
  15:   
  16:              Console.ReadLine();
  17:          }
  18:   
  19:          /// <summary>
20: // This method requires an observer.
  21:          /// </summary>
  22:          private static void Main1()
  23:          {
  24:              var theObserver = new TheObserver();
  25:   
  26:              var ob1 = new Ob1();
  27:              var unsubscribeHandler = ob1.Subscribe(theObserver);
  28:   
  29:              Console.WriteLine("has subscribed...");
  30:              ThreadPool.QueueUserWorkItem(obj => ob1.DoJob(obj));
  31:              Console.WriteLine("has started DoJob()\n");
  32:   
  33:              Console.ReadLine();
  34:          }
  35:      }
  36:   
  37:      public class TheObserver : IObserver<string>
  38:      {
  39:          public void OnCompleted()
  40:          {
  41:              Console.WriteLine("Completed");
  42:          }
  43:   
  44:          public void OnError(Exception exception)
  45:          {
  46:              Console.WriteLine(exception.Message);
  47:          }
  48:   
  49:          public void OnNext(string str)
  50:          {
  51:              Console.WriteLine(str);
  52:          }
  53:      }
  54:   
  55:      public class Ob1 : IObservable<string>
  56:      {
  57:          private List<IObserver<string>> observers = new List<IObserver<string>>();
  58:   
  59:          public IDisposable Subscribe(IObserver<string> observer)
  60:          {
  61:              observers.Add(observer);
  62:              return new Unsubscribe(observer, p => observers.Remove(p)); 
  63:          }
  64:   
  65:          public void DoJob(object obj)
  66:          {
  67:              var sum = 0;
  68:              try
  69:              {
  70:                  for (int i = 0; i < 100; i++)
  71:                  {
  72:                      observers.ForEach(p => p.OnNext((++sum).ToString()));
  73:                      Thread.Sleep(30);
  74:                  }
  75:              }
  76:              catch (Exception ex)
  77:              { 
  78:                  observers.ForEach(p=>p.OnError(ex));
  79:              }
  80:   
  81:              observers.ForEach(p=>p.OnCompleted());
  82:          }
  83:      }
  84:   
  85:      public class Unsubscribe : IDisposable
  86:      {
  87:          public IObserver<string> Source { get; set; }
  88:          public Action<IObserver<string>> DisposeAction { get; set; }
  89:   
  90:          public Unsubscribe(IObserver<string> source, Action<IObserver<string>> disposeAction)
  91:          {
  92:              this.Source = source;
  93:              this.DisposeAction = disposeAction;
  94:          }
  95:   
  96:          public void Dispose()
  97:          {
  98:              DisposeAction(Source);
  99:          }
 100:      }

In system. Reactive. dll, iobservable <t> provides the following extension methods:

   1:  public static class ObservableExtensions
   2:  {
   3:      // Methods
   4:      public static IDisposable Subscribe<TSource>(this IObservable<TSource> source);
   5:      public static IDisposable Subscribe<TSource>(this IObservable<TSource> source, Action<TSource> onNext);
   6:      public static IDisposable Subscribe<TSource>(this IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError);
   7:      public static IDisposable Subscribe<TSource>(this IObservable<TSource> source, Action<TSource> onNext, Action onCompleted);
   8:      public static IDisposable Subscribe<TSource>(this IObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted);
   9:  }
  10:   
  11:   

So we simply wrote:

   1:  static void Main(string[] args)
   2:          {
   3:              var observables = Observable.Interval(TimeSpan.FromMilliseconds(30)).TakeWhile(p => p <= 100);
   4:              var newObservable = observables.Select(p => --p);
   5:              observables.Subscribe(p => Console.WriteLine(p));
   6:              newObservable.Subscribe(c => Console.WriteLine("\t" + c));
   7:              Thread.Sleep(3000);
   8:              Console.WriteLine("start");
   9:              Console.ReadLine();
  10:          }
Here, the Select method of line 5 is called every time the onnext of the observables is generated.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.