Mercurial > pub > ImplabNet
comparison Implab/Diagnostics/TextListenerBase.cs @ 40:fe33f4e02ad5
improved tracing
added text listeners (file,console)
author | cin |
---|---|
date | Tue, 15 Apr 2014 17:52:09 +0400 |
parents | |
children | 7c2369f580b8 |
comparison
equal
deleted
inserted
replaced
39:6498078ae368 | 40:fe33f4e02ad5 |
---|---|
1 using System; | |
2 using System.Collections.Generic; | |
3 using System.Linq; | |
4 using System.Text; | |
5 | |
6 namespace Implab.Diagnostics { | |
7 public abstract class TextListenerBase : ServiceLocator, IEventTextFormatter<object>, IEventTextFormatter<TraceEvent> { | |
8 | |
9 readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>(); | |
10 | |
11 protected TextListenerBase() { | |
12 Register(this); | |
13 } | |
14 | |
15 public void Subscribe(Type eventType) { | |
16 if (eventType == null) | |
17 throw new ArgumentNullException("eventType"); | |
18 GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null); | |
19 } | |
20 | |
21 public void Subscribe<TEvent>() { | |
22 Subscribe<TEvent>(LogChannel<TEvent>.Default); | |
23 } | |
24 | |
25 public void Subscribe<TEvent>(LogChannel<TEvent> channel) { | |
26 if (channel == null) | |
27 throw new ArgumentNullException("channel"); | |
28 | |
29 lock (m_subscriptions) { | |
30 AssertNotDisposed(); | |
31 | |
32 var formatter = GetService<IEventTextFormatter<TEvent>>(); | |
33 | |
34 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => { | |
35 WriteEntry((TraceContext)sender, formatter.Format((TraceContext)sender, args.Value)); | |
36 }; | |
37 | |
38 if (m_subscriptions.ContainsKey(channel)) | |
39 return; | |
40 | |
41 channel.Events += handler; | |
42 | |
43 Action unsubscribe = () => { | |
44 channel.Events -= handler; | |
45 }; | |
46 | |
47 m_subscriptions.Add(channel, unsubscribe); | |
48 } | |
49 } | |
50 | |
51 public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) { | |
52 if (channel == null) | |
53 throw new ArgumentNullException("channel"); | |
54 | |
55 lock (m_subscriptions) { | |
56 Action subscription; | |
57 if (m_subscriptions.TryGetValue(channel, out subscription)) { | |
58 subscription(); | |
59 m_subscriptions.Remove(channel); | |
60 } | |
61 } | |
62 } | |
63 | |
64 public void UnsubscribeAll() { | |
65 lock (m_subscriptions) { | |
66 foreach (var subscription in m_subscriptions.Values) | |
67 subscription(); | |
68 m_subscriptions.Clear(); | |
69 } | |
70 } | |
71 | |
72 protected abstract void WriteEntry(TraceContext context, EventText text); | |
73 | |
74 public EventText Format(TraceContext context, object data) { | |
75 return new EventText { | |
76 indent = context.CurrentOperation.Level, | |
77 content = data.ToString() | |
78 }; | |
79 } | |
80 | |
81 public EventText Format(TraceContext context, TraceEvent data) { | |
82 var level = context.CurrentOperation.Level; | |
83 if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted) | |
84 level--; | |
85 | |
86 return new EventText { | |
87 indent = level, | |
88 content = data.ToString() | |
89 }; | |
90 } | |
91 | |
92 protected override void Dispose(bool disposing) { | |
93 if (disposing) { | |
94 UnsubscribeAll(); | |
95 } | |
96 base.Dispose(disposing); | |
97 } | |
98 } | |
99 } |