Creating a weak subscription to an IObservable

前端 未结 6 1470
暗喜
暗喜 2021-02-01 05:05

What I want to do is ensure that if the only reference to my observer is the observable, it get\'s garbage collected and stops receiving messages.

Say I have a control w

6条回答
  •  忘掉有多难
    2021-02-01 05:49

    this is my implementation (quit simple one)

    public class WeakObservable: IObservable
    {
        private IObservable _source;
    
        public WeakObservable(IObservable source)
        {
            #region Validation
    
            if (source == null)
                throw new ArgumentNullException("source");
    
            #endregion Validation
    
            _source = source;
        }
    
        public IDisposable Subscribe(IObserver observer)
        {
            IObservable source = _source;
            if(source == null)
                return Disposable.Empty;
            var weakObserver = new WaekObserver(observer);
            IDisposable disp = source.Subscribe(weakObserver);
            return disp;
        }
    }
        public class WaekObserver: IObserver
    {
        private WeakReference> _target;
    
        public WaekObserver(IObserver target)
        {
            #region Validation
    
            if (target == null)
                throw new ArgumentNullException("target");
    
            #endregion Validation
    
            _target = new WeakReference>(target);
        }
    
        private IObserver Target
        {
            get
            {
                IObserver target;
                if(_target.TryGetTarget(out target))
                    return target;
                return null;
            }
        }
    
        #region IObserver Members
    
        /// 
        /// Notifies the observer that the provider has finished sending push-based notifications.
        /// 
        public void OnCompleted()
        {
            IObserver target = Target;
            if (target == null)
                return;
    
            target.OnCompleted();
        }
    
        /// 
        /// Notifies the observer that the provider has experienced an error condition.
        /// 
        /// An object that provides additional information about the error.
        public void OnError(Exception error)
        {
            IObserver target = Target;
            if (target == null)
                return;
    
            target.OnError(error);
        }
    
        /// 
        /// Provides the observer with new data.
        /// 
        /// The current notification information.
        public void OnNext(T value)
        {
            IObserver target = Target;
            if (target == null)
                return;
    
            target.OnNext(value);
        }
    
        #endregion IObserver Members
    }
        public static class RxExtensions
    {
        public static IObservable ToWeakObservable(this IObservable source)
        {
            return new WeakObservable(source);
        }
    }
            static void Main(string[] args)
        {
            Console.WriteLine("Start");
            var xs = Observable.Interval(TimeSpan.FromSeconds(1));
            Sbscribe(xs);
    
            Thread.Sleep(2020);
            Console.WriteLine("Collect");
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            Console.WriteLine("Done");
            Console.ReadKey();
        }
    
        private static void Sbscribe(IObservable source)
        {
            source.ToWeakObservable().Subscribe(v => Console.WriteLine(v));
        }
    

提交回复
热议问题