Created
July 12, 2012 05:08
-
-
Save jkhk/3095967 to your computer and use it in GitHub Desktop.
WeakEvents demo with Rx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.ObjectModel; | |
using System.Collections.Specialized; | |
using System.Reactive; | |
using System.Reactive.Linq; | |
namespace WeakEvents | |
{ | |
internal class Program | |
{ | |
private static void Main(string[] args) | |
{ | |
var collection = new ObservableCollection<object>(); | |
var strongSubscriber = new StrongSubscriber(); | |
strongSubscriber.Subscribe(collection); | |
var weakSubscriber = new WeakSubscriber(); | |
weakSubscriber.Subscribe(collection); | |
collection.Add(new object()); | |
strongSubscriber = null; | |
weakSubscriber = null; | |
GC.Collect(); | |
Console.WriteLine("Full collection completed"); | |
collection.Add(new object()); | |
Console.Read(); | |
} | |
} | |
class StrongSubscriber | |
{ | |
public void Subscribe(ObservableCollection<object> collection) | |
{ | |
collection.CollectionChanged += delegate | |
{ | |
Console.WriteLine("Event Received By Strong Subscription"); | |
}; | |
} | |
} | |
class WeakSubscriber | |
{ | |
public void Subscribe(ObservableCollection<object> collection) | |
{ | |
collection.ObserveCollectionChanged().SubscribeWeakly(this, (target, item) => target.HandleEvent(item)); | |
} | |
private void HandleEvent(EventPattern<NotifyCollectionChangedEventArgs> item) | |
{ | |
Console.WriteLine("Event Received by Weak subscription"); | |
} | |
} | |
public static class ObservableExtensions | |
{ | |
public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>> ObserveCollectionChanged(this INotifyCollectionChanged collection) | |
{ | |
return Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>( | |
handler => collection.CollectionChanged += handler, | |
handler => collection.CollectionChanged -= handler); | |
} | |
public static IDisposable SubscribeWeakly<T, TTarget>(this IObservable<T> observable, TTarget target, Action<TTarget, T> onNext) where TTarget : class | |
{ | |
var reference = new WeakReference(target); | |
if (onNext.Target != null) | |
{ | |
throw new ArgumentException("onNext must refer to a static method, or else the subscription will still hold a strong reference to target"); | |
} | |
IDisposable subscription = null; | |
subscription = observable.Subscribe(item => | |
{ | |
var currentTarget = reference.Target as TTarget; | |
if (currentTarget != null) | |
{ | |
onNext(currentTarget, item); | |
} | |
else | |
{ | |
subscription.Dispose(); | |
} | |
}); | |
return subscription; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment