Mercurial > pub > ImplabNet
diff Implab/Diagnostics/ListenerBase.cs @ 134:04d4c92d0f28 v2
Improved logging
author | cin |
---|---|
date | Wed, 11 Feb 2015 02:12:15 +0300 |
parents | |
children | 240aa6994018 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Diagnostics/ListenerBase.cs Wed Feb 11 02:12:15 2015 +0300 @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Implab.Diagnostics { + public abstract class ListenerBase : ServiceLocator, ILogWriter<object>, ILogWriter<TraceEvent> { + + readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>(); + + protected ListenerBase() { + Register(this); + } + + public void Subscribe(Type eventType) { + if (eventType == null) + throw new ArgumentNullException("eventType"); + GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null); + } + + public void Subscribe<TEvent>() { + Subscribe<TEvent>(LogChannel<TEvent>.Default); + } + + public void Subscribe<TEvent>(LogChannel<TEvent> channel) { + if (channel == null) + throw new ArgumentNullException("channel"); + + lock (m_subscriptions) { + AssertNotDisposed(); + if (m_subscriptions.ContainsKey(channel)) + return; + + var writer = GetService<ILogWriter<TEvent>>(); + + EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => writer.Write(args,args.Value); + + channel.Events += handler; + + Action unsubscribe = () => { + channel.Events -= handler; + }; + + m_subscriptions.Add(channel, unsubscribe); + } + } + + public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) { + if (channel == null) + throw new ArgumentNullException("channel"); + + lock (m_subscriptions) { + Action subscription; + if (m_subscriptions.TryGetValue(channel, out subscription)) { + subscription(); + m_subscriptions.Remove(channel); + } + } + } + + public void UnsubscribeAll() { + lock (m_subscriptions) { + foreach (var subscription in m_subscriptions.Values) + subscription(); + m_subscriptions.Clear(); + } + } + + #region ILogWriter implementation + public abstract void Write(LogEventArgs args, object entry); + #endregion + + #region ILogWriter implementation + public virtual void Write(LogEventArgs args, TraceEvent entry) { + Write(args, (object)entry); + } + #endregion + + + protected override void Dispose(bool disposing) { + base.Dispose(disposing); + if (disposing) { + UnsubscribeAll(); + } + } + } +}