У меня есть ситуация, когда у нас есть долгоживущий набор данных (издатель), который предоставляется пользователю с помощью WinForms (подписчики).Поскольку данные модифицируются, мы хотим, чтобы пользовательский интерфейс также обновлялся.Первоначальная идея заключалась в том, чтобы использовать события и подписывать пользовательский интерфейс на события на издателе.Однако это приведет к утечке памяти, поскольку данные устаревают из различных частей пользовательского интерфейса, которые могут приходить и уходить, представляя его.
Выполняя небольшое копание, я наткнулся на WeakEventManager и связанный с ним шаблон на MSDN .Хотя это выглядит как решение, оно вводит не совсем базовое изменение шаблона использования посредника (пользовательская реализация WeakEventManager) между издателем и подписчиком.В нашем магазине разработчики постоянно переключаются между продуктами и языками, и я обеспокоен тем, что через 10 лет бедному разработчику, обслуживающему код, придется потратить слишком много времени, пытаясь понять WeakEventManager и этот шаблон.
Поскольку WeakEventManager уже нарушает стандартный механизм подписки на события, а унаследованная реализация имеет длину более нескольких строк, мне было интересно, есть ли у него реальное преимущество по сравнению с чем-то вроде следующего, которое более понятно и может быть добавлено непосредственно виздатель (без посредника).Мысли?
Подписчики будут реализовывать такой интерфейс, как:
public interface IDataChangedListener
{
void OnDataChanged(Object model);
}
И у издателя будет что-то вроде этого:
private static List<WeakReference> listeners = new List<WeakReference>();
public static void AddListener(IDataChangedListener listener)
{
lock (listener)
{
listeners.Add(new WeakReference(listener));
}
}
public static void RemoveListener(IDataChangedListener listener)
{
lock (listener)
{
listeners.RemoveAll(x => x.Target == listener);
}
}
private static void NotifyListeners(object model)
{
lock (listeners)
{
listeners.RemoveAll(x => !x.IsAlive); //Purge
foreach (IDataChangedListener listener in listeners)
{
if (listener != null)
{
listener.OnDataChanged(model);
}
}
}
}
Мысли?