diff --git a/Implab.Playground/Implab.Playground.csproj b/Implab.Playground/Implab.Playground.csproj --- a/Implab.Playground/Implab.Playground.csproj +++ b/Implab.Playground/Implab.Playground.csproj @@ -1,6 +1,6 @@  - netcoreapp2.0 + netcoreapp2.0;;net46 /usr/lib/mono/4.6-api/ diff --git a/Implab.Playground/Program.cs b/Implab.Playground/Program.cs --- a/Implab.Playground/Program.cs +++ b/Implab.Playground/Program.cs @@ -24,9 +24,16 @@ namespace Implab.Playground { public class Program { static void Main(string[] args) { + Trace.Log("First!"); + Log("+1!"); - using(TraceRegistry.Global.Subscribe(ch => { + using(TraceRegistry.Global.Subscribe(x => { + var ch = x as TraceSourceChannel; + if (ch == null) + return; + Console.WriteLine($"{ch.Id}: {ch.Source.Name}"); + }, true)) { Trace.Log("Hi!"); Log("Respect!"); diff --git a/Implab.Test/DiagnosticsTest.cs b/Implab.Test/DiagnosticsTest.cs new file mode 100644 --- /dev/null +++ b/Implab.Test/DiagnosticsTest.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Implab.Components; +using Implab.Diagnostics; +using Xunit; + +namespace Implab.Test { + + public class DiagnosticsTest { + class Foo {} + + [Fact] + public void TestRegistration() { + var channel = TraceSourceChannel.Default; + + Assert.Equal(typeof(Foo), channel.Id); + Assert.Equal(typeof(Foo).FullName, channel.Source.Name); + + TraceSourceChannel found = null; + int visited = 0; + + TraceRegistry.Global.Subscribe(x => { + visited++; + found = x as TraceSourceChannel; + }, false); + + Assert.Equal(0, visited); + + TraceRegistry.Global.Subscribe(x => { + visited++; + found = x as TraceSourceChannel; + }, true); + + Assert.Equal(1,visited); + Assert.Equal(channel, found); + + } + + } +} \ No newline at end of file diff --git a/Implab/Diagnostics/ChannelInfo.cs b/Implab/Diagnostics/ChannelInfo.cs deleted file mode 100644 --- a/Implab/Diagnostics/ChannelInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Diagnostics; - -namespace Implab.Diagnostics -{ - public class ChannelInfo - { - internal ChannelInfo(object id, TraceSource source) { - Debug.Assert(id != null); - Debug.Assert(source != null); - - Id = id; - Source = source; - - } - - public object Id { get; private set; } - - public TraceSource Source { get; private set; } - - - } -} \ No newline at end of file diff --git a/Implab/Diagnostics/Trace.cs b/Implab/Diagnostics/Trace.cs --- a/Implab/Diagnostics/Trace.cs +++ b/Implab/Diagnostics/Trace.cs @@ -12,16 +12,23 @@ using System.Threading.Tasks; namespace Implab.Diagnostics { /// /// Static class which creates an individual for - /// the type specified in the parameter . + /// the type specified in the parameter and uses + /// it to perform logging operations. /// /// The type for which tracing is demanded. public static class Trace { readonly static Lazy _trace = new Lazy(() => TraceSourceChannel.Default.Source); + /// + /// The associated with the current class. + /// TraceSource is created using . + /// public static TraceSource TraceSource { get { return _trace.Value; } } #if NETFX_TRACE_BUG + // AsyncLocal will store value inside the current execution context + // and will force it to be copied... not a very effective solution. readonly static AsyncLocal m_currentOperation = new AsyncLocal(); #endif diff --git a/Implab/Diagnostics/TraceChannelRegistry.cs b/Implab/Diagnostics/TraceChannelRegistry.cs deleted file mode 100644 --- a/Implab/Diagnostics/TraceChannelRegistry.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using Implab.Parallels; - -namespace Implab.Diagnostics { - public class TraceChannelRegistry { - - class Subscription : IDisposable { - readonly Action m_unsubscribe; - - public Subscription(Action unsubscribe) { - m_unsubscribe = unsubscribe; - } - - public void Dispose() { - m_unsubscribe(this); - } - } - - public static TraceChannelRegistry AllCannels { get; } = new TraceChannelRegistry(); - - readonly object m_lock = new object(); - - readonly Dictionary> m_subscriptions = new Dictionary>(); - readonly SimpleAsyncQueue m_channels = new SimpleAsyncQueue(); - - internal void NotifyChannelCreated(ChannelInfo channel) { - // notifications can run in parallel - Action[] handlers = null; - - lock(m_lock) { - m_channels.Enqueue(channel); - if (m_subscriptions.Count > 0) { - handlers = new Action[m_subscriptions.Count]; - m_subscriptions.Values.CopyTo(handlers, 0); - } - } - - if (handlers != null) - foreach(var h in handlers) - h(channel); - } - - /// - /// Subscribes the specified handler to notifications about new trace - /// channels - /// - /// - /// - public IDisposable Subscribe(Action handler, bool existing) { - Safe.ArgumentNotNull(handler, nameof(handler)); - - var cookie = new Subscription(RemoveSubscription); - - IEnumerable snap; - - lock(m_lock) { - m_subscriptions.Add(cookie, handler); - snap = m_channels.Snapshot(); - } - - if (existing) { - foreach(var c in snap) - handler(c); - } - - return cookie; - } - - void RemoveSubscription(object cookie) { - lock(m_lock) - m_subscriptions.Remove(cookie); - } - } -} \ No newline at end of file diff --git a/Implab/Diagnostics/TraceSourceChannel`1.cs b/Implab/Diagnostics/TraceSourceChannel`1.cs --- a/Implab/Diagnostics/TraceSourceChannel`1.cs +++ b/Implab/Diagnostics/TraceSourceChannel`1.cs @@ -23,7 +23,7 @@ namespace Implab.Diagnostics { public static TraceSourceChannel Default { get { return _traceSource.Value; } } static TraceSourceChannel CreateChannel() { - var channel = new TraceSourceChannel(typeof(T), typeof(T).Name); + var channel = new TraceSourceChannel(typeof(T), typeof(T).FullName); TraceRegistry.Global.Register(channel);