andrew4582

Observable

Mar 4th, 2011
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.94 KB | None | 0 0
  1. class Observable<T>:IObservable<T>,IDisposable {
  2.             private Dictionary<int,IObserver<T>> subscribers = new Dictionary<int,IObserver<T>>();
  3.             private readonly object thisLock = new object();
  4.             private int key;
  5.             private bool isDisposed;
  6.  
  7.             public void Dispose() {
  8.                 Dispose(true);
  9.             }
  10.  
  11.             protected virtual void Dispose(bool disposing) {
  12.                 if(disposing) {
  13.                     OnCompleted();
  14.                     isDisposed = true;
  15.                 }
  16.             }
  17.  
  18.             protected void OnNext(T value) {
  19.                 if(isDisposed) {
  20.                     throw new ObjectDisposedException("Observable<T>");
  21.                 }
  22.  
  23.                 foreach(IObserver<T> observer in subscribers.Select(kv => kv.Value)) {
  24.                     observer.OnNext(value);
  25.                 }
  26.             }
  27.  
  28.             protected void OnError(Exception exception) {
  29.                 if(isDisposed) {
  30.                     throw new ObjectDisposedException("Observable<T>");
  31.                 }
  32.  
  33.                 if(exception == null) {
  34.                     throw new ArgumentNullException("exception");
  35.                 }
  36.  
  37.                 foreach(IObserver<T> observer in subscribers.Select(kv => kv.Value)) {
  38.                     observer.OnError(exception);
  39.                 }
  40.             }
  41.  
  42.             protected void OnCompleted() {
  43.                 if(isDisposed) {
  44.                     throw new ObjectDisposedException("Observable<T>");
  45.                 }
  46.  
  47.                 foreach(IObserver<T> observer in subscribers.Select(kv => kv.Value)) {
  48.                     observer.OnCompleted();
  49.                 }
  50.             }
  51.  
  52.             public IDisposable Subscribe(IObserver<T> observer) {
  53.                 if(observer == null) {
  54.                     throw new ArgumentNullException("observer");
  55.                 }
  56.  
  57.                 lock(thisLock) {
  58.                     int k = key++;
  59.                     subscribers.Add(k,observer);
  60.                     return new AnonymousDisposable(() => {
  61.                         lock(thisLock) {
  62.                             subscribers.Remove(k);
  63.                         }
  64.                     });
  65.                 }
  66.             }
  67.         }
  68.  
  69.         class AnonymousDisposable:IDisposable {
  70.             Action dispose;
  71.             public AnonymousDisposable(Action dispose) {
  72.                 this.dispose = dispose;
  73.             }
  74.  
  75.             public void Dispose() {
  76.                 dispose();
  77.             }
  78.         }
  79.  
  80.         public class AnonymousObservable<T>:IObservable<T> {
  81.             private Func<IObserver<T>,IDisposable> _subscribe;
  82.             public AnonymousObservable(Func<IObserver<T>,IDisposable> subscribe) {
  83.                 _subscribe = subscribe;
  84.             }
  85.  
  86.             public IDisposable Subscribe(IObserver<T> observer) {
  87.                 return _subscribe(observer);
  88.             }
  89.         }
Advertisement
Add Comment
Please, Sign In to add comment