Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /== основное ======================================================================================/
- /== нагло позаимствовано и доработано напильником =================================================/
- /== http://www.thomaslevesque.com/2010/05/17/c-a-simple-implementation-of-the-weakevent-pattern/ ==/
- public class WeakDelegate<T> : IEquatable<T>
- {
- private WeakReference mTargetReference;
- private MethodInfo mMethod;
- public WeakDelegate(Delegate RealDelegate)
- {
- if (RealDelegate.Target != null)
- {
- mTargetReference = new WeakReference(RealDelegate.Target);
- }
- else
- {
- mTargetReference = null;
- }
- mMethod = RealDelegate.Method;
- }
- public bool IsAlive
- {
- get
- {
- return ((mTargetReference == null) || (mTargetReference.IsAlive));
- }
- }
- internal void Invoke(params object[] Args)
- {
- if (mTargetReference != null)
- {
- mMethod.Invoke(mTargetReference.Target, Args);
- }
- }
- #region Члены IEquatable<T>
- public bool Equals(T OtherEventHandler)
- {
- if (!IsAlive) return false;
- Delegate D = (Delegate)((object)OtherEventHandler);
- if (D == null) return false;
- if (mTargetReference.Target != D.Target) return false;
- if (!mMethod.Equals(D.Method)) return false;
- return true;
- }
- #endregion
- public override string ToString()
- {
- string T = "Target = " + (mTargetReference.IsAlive ? mTargetReference.Target.ToString() : "is null.");
- return T + " " + mMethod.ToString();
- }
- }
- public class WeakEvent<TEventHandler>
- {
- private List<WeakDelegate<TEventHandler>> mHandlers;
- public WeakEvent()
- {
- mHandlers = new List<WeakDelegate<TEventHandler>>();
- }
- public virtual void AddHandler(TEventHandler Handler)
- {
- Delegate D = (Delegate)(object)Handler;
- mHandlers.Add(new WeakDelegate<TEventHandler>(D));
- RemoveDeadHandlers();
- }
- public virtual void RemoveHandler(TEventHandler Handler)
- {
- RemoveEqualsHandlers(Handler);
- RemoveDeadHandlers();
- // сдохни ебаная лямда
- //mHandlers.RemoveAll(wd => !wd.IsAlive || wd.Equals(Handler));
- }
- private void RemoveEqualsHandlers(TEventHandler Handler)
- {
- EqualsHandlersPredicate<TEventHandler> P = new EqualsHandlersPredicate<TEventHandler>(Handler);
- mHandlers.RemoveAll(P.Predicate);
- }
- private void RemoveDeadHandlers()
- {
- NotAliveHandlersPredicate<TEventHandler> P = new NotAliveHandlersPredicate<TEventHandler>();
- mHandlers.RemoveAll(P.Predicate);
- }
- public virtual void Raise(params object[] Args)
- {
- // удолить ??
- var Handlers = mHandlers.ToArray();
- foreach (var WeakDelegate in Handlers)
- {
- if (WeakDelegate.IsAlive)
- {
- WeakDelegate.Invoke(Args);
- }
- else
- {
- // удолить ??
- mHandlers.Remove(WeakDelegate);
- }
- }
- }
- // временно для теста
- public List<WeakDelegate<TEventHandler>> Handlers
- {
- get { return mHandlers; }
- }
- }
- public class NotAliveHandlersPredicate<TEventHandler>
- {
- public bool Predicate(WeakDelegate<TEventHandler> OtherWeakDelegate)
- {
- return (!OtherWeakDelegate.IsAlive);
- }
- }
- public class EqualsHandlersPredicate<TEventHandler>
- {
- public TEventHandler Handler;
- public EqualsHandlersPredicate(TEventHandler Handler)
- {
- this.Handler = Handler;
- }
- public bool Predicate(WeakDelegate<TEventHandler> OtherWeakDelegate)
- {
- return OtherWeakDelegate.Equals(Handler);
- }
- }
- /== тест =======================================================================/
- public class EventSourceW
- {
- private WeakEvent<Action<string>> mHandlersOnEmitString = new WeakEvent<Action<string>>();
- public event Action<string> OnEmitString
- {
- add { mHandlersOnEmitString.AddHandler(value); }
- remove { mHandlersOnEmitString.RemoveHandler(value); }
- }
- public void RaiseOnEmitString(string S)
- {
- Console.WriteLine("Raise OnEmitString with " + S);
- mHandlersOnEmitString.Raise(S);
- }
- private WeakEvent<Action<int>> mHandlersOnEmitInt = new WeakEvent<Action<int>>();
- public event Action<int> OnEmitInt
- {
- add { mHandlersOnEmitInt.AddHandler(value); }
- remove { mHandlersOnEmitInt.RemoveHandler(value); }
- }
- public void RaiseOnEmitInt(int I)
- {
- Console.WriteLine("Raise OnEmitInt with " + I.ToString());
- mHandlersOnEmitInt.Raise(I);
- }
- public void PrintHandlersList()
- {
- Console.WriteLine();
- Console.WriteLine("Handlers OnEmitInt:");
- for (int i = 0; i < mHandlersOnEmitInt.Handlers.Count; i++)
- {
- Console.WriteLine(mHandlersOnEmitInt.Handlers[i].ToString());
- }
- Console.WriteLine();
- Console.WriteLine("Handlers OnEmitString:");
- for (int i = 0; i < mHandlersOnEmitString.Handlers.Count; i++)
- {
- Console.WriteLine(mHandlersOnEmitString.Handlers[i].ToString());
- }
- Console.WriteLine();
- }
- }
- public class EventLisnerW
- {
- public void SubscribeOnEvent(EventSourceW ES)
- {
- Console.WriteLine("Listner subscribe...");
- ES.OnEmitInt += GetInt;
- ES.OnEmitString += GetString;
- }
- public void UnSubscribeOnEvent(EventSource ES)
- {
- Console.WriteLine("Listner unsubscribe...");
- ES.OnEmitInt -= GetInt;
- ES.OnEmitString -= GetString;
- }
- public void GetInt(int I)
- {
- Console.WriteLine("GetInt = " + I.ToString());
- }
- public void GetString(string S)
- {
- Console.WriteLine("GetString = " + S);
- }
- }
- public static class TestWeakEventsW
- {
- private static EventSourceW mS;
- private static EventLisnerW mL;
- private static long mStartMemUse = 0;
- public static void MainTest()
- {
- Console.WriteLine("GC.MaxGeneration = " + GC.MaxGeneration.ToString());
- mStartMemUse = GC.GetTotalMemory(true);
- Console.WriteLine("GC.GetTotalMemory = " + mStartMemUse.ToString());
- mS = new EventSourceW();
- for (int i = 0; i < 10000; i++)
- {
- Console.WriteLine();
- Console.WriteLine("New Listner {0}...", (i + 1));
- mL = new EventLisnerW();
- mL.SubscribeOnEvent(mS);
- mS.RaiseOnEmitInt(RandomInt());
- mS.RaiseOnEmitInt(RandomInt());
- Console.WriteLine("GC.Collect...");
- GC.Collect();
- mS.RaiseOnEmitInt(RandomInt());
- mS.RaiseOnEmitInt(RandomInt());
- Console.WriteLine("Listner == null.");
- mL = null;
- Console.WriteLine("GC.Collect...");
- GC.Collect();
- mS.RaiseOnEmitInt(RandomInt());
- mS.RaiseOnEmitInt(RandomInt());
- if ((i % 5) == 0)
- {
- mS.RaiseOnEmitString("Test OnEmitString for 6 iteration...");
- }
- mS.RaiseOnEmitInt(RandomInt());
- mS.RaiseOnEmitInt(RandomInt());
- mS.PrintHandlersList();
- Console.WriteLine("GC.GetTotalMemory = " + (GC.GetTotalMemory(true)).ToString());
- //Console.ReadKey();
- }
- Console.WriteLine("Start mem = {0}", mStartMemUse);
- Console.WriteLine();
- Console.WriteLine("Happy End...");
- }
- private static Random mRandom = new Random();
- private static int RandomInt()
- {
- return mRandom.Next(100);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment