Skip to content

Instantly share code, notes, and snippets.

@jkhk
Created July 12, 2012 05:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkhk/3095967 to your computer and use it in GitHub Desktop.
Save jkhk/3095967 to your computer and use it in GitHub Desktop.
WeakEvents demo with Rx
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