# HG changeset patch # User cin # Date 2014-10-22 14:37:56 # Node ID 4c0e5ef99986818ce3b22f8dd2ed60583d7df8c4 # Parent cdaaf4792c22120387bd1fd4981a32535e6ba2b7 rewritten tracing diff --git a/Implab.Diagnostics.Interactive/InteractiveListener.cs b/Implab.Diagnostics.Interactive/InteractiveListener.cs --- a/Implab.Diagnostics.Interactive/InteractiveListener.cs +++ b/Implab.Diagnostics.Interactive/InteractiveListener.cs @@ -107,11 +107,11 @@ namespace Implab.Diagnostics.Interactive base.Dispose(disposing); } - protected override void WriteEntry(TraceContext context, EventText text, string channel) { + protected override void WriteEntry(LogEventArgs args, EventText text, string channel) { var item = new TraceViewItem { Indent = text.indent, Message = text.content, - Thread = context.ThreadId, + Thread = args.ThreadId, Channel = channel, Timestamp = Environment.TickCount }; diff --git a/Implab/Diagnostics/ConsoleTraceListener.cs b/Implab/Diagnostics/ConsoleTraceListener.cs --- a/Implab/Diagnostics/ConsoleTraceListener.cs +++ b/Implab/Diagnostics/ConsoleTraceListener.cs @@ -18,16 +18,16 @@ namespace Implab.Diagnostics { } - protected override void WriteEntry(TraceContext context, EventText text, string channel) { + protected override void WriteEntry(LogEventArgs args, EventText text, string channel) { var msg = new StringBuilder(); for (int i = 0; i < text.indent; i++) msg.Append(" "); - msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content); + msg.AppendFormat("[{0}]:{1}: {2}", args.ThreadId, channel, text.content); lock (_consoleLock) { - Console.ForegroundColor = (ConsoleColor)(context.ThreadId % 15 + 1); - Console.WriteLine(msg.ToString()); + Console.ForegroundColor = (ConsoleColor)(args.ThreadId % 15 + 1); + Console.WriteLine(msg); } } } diff --git a/Implab/Diagnostics/Extensions.cs b/Implab/Diagnostics/Extensions.cs new file mode 100644 --- /dev/null +++ b/Implab/Diagnostics/Extensions.cs @@ -0,0 +1,15 @@ +namespace Implab.Diagnostics { + public static class Extensions { + public static IPromise EndLogicalOperation(this IPromise promise) { + Safe.ArgumentNotNull(promise, "promise"); + var op = TraceContext.Instance.DetachLogicalOperation(); + + return promise.Anyway(() => { + TraceContext.Instance.EnterLogicalOperation(op,true); + TraceLog.EndLogicalOperation(); + TraceContext.Instance.Leave(); + }); + } + } +} + diff --git a/Implab/Diagnostics/IEventTextFormatter.cs b/Implab/Diagnostics/IEventTextFormatter.cs --- a/Implab/Diagnostics/IEventTextFormatter.cs +++ b/Implab/Diagnostics/IEventTextFormatter.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Implab.Diagnostics { +namespace Implab.Diagnostics { public interface IEventTextFormatter { - EventText Format(TraceContext context, TEvent data); + EventText Format(LogEventArgs args, TEvent data); } } diff --git a/Implab/Diagnostics/LogChannel.cs b/Implab/Diagnostics/LogChannel.cs --- a/Implab/Diagnostics/LogChannel.cs +++ b/Implab/Diagnostics/LogChannel.cs @@ -27,8 +27,8 @@ namespace Implab.Diagnostics { /// /// Событие появление новой записи в журнале, на это событие подписываются слушатели. /// - public event EventHandler> Events; - + public event EventHandler> Events; + /// /// Имя канала, полезно для отображения в журнале /// @@ -63,19 +63,18 @@ namespace Implab.Diagnostics { /// public void LogEvent(TEvent data) { var t = Events; - if (t!= null) - t(TraceContext.Current,new ValueEventArgs(data)); - } - - /// - /// Отправляет запись журнала через канал подписчикам. - /// - /// Запись журнала. - /// Контекст трассировки от которого рассылается сообщение/ - public void LogEvent(TraceContext context,TEvent data) { - var t = Events; - if (t != null) - t(context, new ValueEventArgs(data)); + if (t != null) { + var traceContext = TraceContext.Instance; + t( + this, + new LogEventArgs( + data, + traceContext.ThreadId, + traceContext.CurrentOperation, + traceContext.CurrentOperation.Duration + ) + ); + } } } } diff --git a/Implab/Diagnostics/LogEventArgs.cs b/Implab/Diagnostics/LogEventArgs.cs new file mode 100644 --- /dev/null +++ b/Implab/Diagnostics/LogEventArgs.cs @@ -0,0 +1,24 @@ +using System; + +namespace Implab.Diagnostics { + public class LogEventArgs : EventArgs { + public int ThreadId { + get; + private set; + } + public LogicalOperation Operation { + get; + private set; + } + public int OperationTimeOffset { + get; + private set; + } + public LogEventArgs(int threadId, LogicalOperation operation, int timeOffset) { + ThreadId = threadId; + Operation = operation; + OperationTimeOffset = timeOffset; + } + } +} + diff --git a/Implab/Diagnostics/LogEventArgsT.cs b/Implab/Diagnostics/LogEventArgsT.cs new file mode 100644 --- /dev/null +++ b/Implab/Diagnostics/LogEventArgsT.cs @@ -0,0 +1,13 @@ +namespace Implab.Diagnostics { + public class LogEventArgs : LogEventArgs { + public TEvent Value { + get; + private set; + } + + public LogEventArgs(TEvent value, int threadId, LogicalOperation operation, int timeOffset) : base(threadId, operation, timeOffset) { + Value = value; + } + } +} + diff --git a/Implab/Diagnostics/LogicalOperation.cs b/Implab/Diagnostics/LogicalOperation.cs --- a/Implab/Diagnostics/LogicalOperation.cs +++ b/Implab/Diagnostics/LogicalOperation.cs @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Implab.Diagnostics { public class LogicalOperation { + public static readonly LogicalOperation EMPTY = new LogicalOperation("__EMPTY__", null); + readonly LogicalOperation m_parent; readonly string m_name; readonly int m_level; diff --git a/Implab/Diagnostics/OperationContext.cs b/Implab/Diagnostics/OperationContext.cs new file mode 100644 --- /dev/null +++ b/Implab/Diagnostics/OperationContext.cs @@ -0,0 +1,49 @@ +namespace Implab.Diagnostics { + struct OperationContext { + readonly LogicalOperation m_initial; + public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false); + LogicalOperation m_current; + readonly bool m_ownership; + + public OperationContext(LogicalOperation operation, bool ownership) { + Safe.ArgumentNotNull(operation, "operation"); + + m_initial = operation; + m_current = operation; + m_ownership = ownership; + } + + public LogicalOperation CurrentOperation { + get { return m_current; } + } + + public void BeginLogicalOperation(string name) { + m_current = new LogicalOperation(name, m_current); + } + + public LogicalOperation DetachLogicalOperation() { + var detached = m_current; + if (m_current != LogicalOperation.EMPTY) { + if (m_current != m_initial) + m_current = m_current.Parent; + else if (m_ownership) + m_current = LogicalOperation.EMPTY; + else + detached = LogicalOperation.EMPTY; + } + TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context"); + return detached; + } + + public void EndLogicalOperation() { + if (m_current != m_initial) { + m_current = m_current.Parent; + } else if (m_current != null && m_ownership) { + m_current = null; + } else { + TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context"); + } + } + } +} + diff --git a/Implab/Diagnostics/TextFileListener.cs b/Implab/Diagnostics/TextFileListener.cs --- a/Implab/Diagnostics/TextFileListener.cs +++ b/Implab/Diagnostics/TextFileListener.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; namespace Implab.Diagnostics { @@ -16,16 +14,16 @@ namespace Implab.Diagnostics { Register(this); } - protected override void WriteEntry(TraceContext context, EventText text, string channel) { + protected override void WriteEntry(LogEventArgs args, EventText text, string channel) { var msg = new StringBuilder(); for (int i = 0; i < text.indent; i++) msg.Append(" "); - msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content); + msg.AppendFormat("[{0}]:{1}: {2}", args.ThreadId, channel, text.content); lock (m_textWriter) { if (!IsDisposed) { // тут гарантировано еще не освобожден m_textWriter - m_textWriter.WriteLine(msg.ToString()); + m_textWriter.WriteLine(msg); m_textWriter.Flush(); } } diff --git a/Implab/Diagnostics/TextListenerBase.cs b/Implab/Diagnostics/TextListenerBase.cs --- a/Implab/Diagnostics/TextListenerBase.cs +++ b/Implab/Diagnostics/TextListenerBase.cs @@ -13,7 +13,7 @@ namespace Implab.Diagnostics { protected TextListenerBase(bool global) { Register(this); if (!global) { - m_boundOperation = TraceContext.Current.CurrentOperation; + m_boundOperation = TraceContext.Instance.CurrentOperation; m_baseIndent = Math.Max(0, m_boundOperation.Level - 1); } } @@ -38,13 +38,12 @@ namespace Implab.Diagnostics { var formatter = GetService>(); var channelName = channel.Name; - EventHandler> handler = (sender, args) => { - TraceContext context = (TraceContext)sender; - var text = formatter.Format(context, args.Value); + EventHandler> handler = (sender, args) => { + var text = formatter.Format(args, args.Value); text.indent -= m_baseIndent; - if (IsRelated(context.CurrentOperation)) - WriteEntry(context, text, channelName); + if (IsRelated(args.Operation)) + WriteEntry(args, text, channelName); }; if (m_subscriptions.ContainsKey(channel)) @@ -97,19 +96,19 @@ namespace Implab.Diagnostics { /// Данный метод может вызваться из разных потоков одновременно. Возможна ситуация, когда /// данный метод вызывается уже после освобождения ообъекта методом . /// - /// Контекст трассировки. /// Текст сообщения. - protected abstract void WriteEntry(TraceContext context, EventText text, string channel); + /// + protected abstract void WriteEntry(LogEventArgs args, EventText text, string channel); - public EventText Format(TraceContext context, object data) { + public EventText Format(LogEventArgs args, object data) { return new EventText { - indent = context.CurrentOperation.Level, + indent = args.Operation.Level, content = data.ToString() }; } - public EventText Format(TraceContext context, TraceEvent data) { - var level = context.CurrentOperation.Level; + public EventText Format(LogEventArgs args, TraceEvent data) { + var level = args.Operation.Level; if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted) level--; diff --git a/Implab/Diagnostics/TraceContext.cs b/Implab/Diagnostics/TraceContext.cs --- a/Implab/Diagnostics/TraceContext.cs +++ b/Implab/Diagnostics/TraceContext.cs @@ -1,238 +1,79 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Implab.Diagnostics { - /// - /// Контекст трассировки, привязывается к потоку и содержит в себе информацию о стеке логических операций. - /// - /// - /// Контекст трассировки передается слушателям событий для определения места, где возникло событие. - /// - public class TraceContext { - LogicalOperation m_currentOperation; - readonly LogicalOperation m_bound; - readonly int m_threadId; - - [ThreadStatic] - static TraceContext _current; - - /// - /// Текущий контекст трассировки для потока, создается астоматически при первом обращении. - /// - public static TraceContext Current { - get { - if (_current == null) { - _current = new TraceContext(); - _current.LogEvent(TraceEventType.Created,"[{0}]", _current.ThreadId); - } - return _current; - } - } - - TraceContext(TraceContext context) - : this(context, false) { - } - - TraceContext(TraceContext context, bool attach) { - if (context == null) - throw new ArgumentNullException("context"); - - m_currentOperation = context.CurrentOperation; - m_bound = attach ? context.BoundOperation : context.CurrentOperation; - m_threadId = Thread.CurrentThread.ManagedThreadId; - } - - TraceContext() { - m_currentOperation = new LogicalOperation(); - m_bound = m_currentOperation; - m_threadId = Thread.CurrentThread.ManagedThreadId; - } - - /// - /// При необходимости копирует состояние контекста трассивровки в текущий поток. - /// - /// Исходный контекст трассировки, который передается. - /// - /// - /// Копирование происходит за счет создания нового контекста трассировки и заполнением его - /// состояния из переданного контекста. При этом копируется стек операций, однако в новом - /// контексте ранее начатые логические операции не могут быть завершены. - /// - /// - /// Если передача состояния состоялась, то вызывается событие трассировки . - /// - /// - public static void Fork(TraceContext from) { - if (_current == from) - return; - if (from != null) { - var context = new TraceContext(from); - context.LogEvent(TraceEventType.Fork, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId); - _current = context; - } else { - _current = new TraceContext(); - } - } - - /// - /// Задает текущему потоку указанный контекст, текущей поток может заканчивать ранее начатые - /// логические операции в указанном контексте. - /// - /// - public static void Attach(TraceContext source) { - if (_current == source) - return; - if (source != null) { - var context = new TraceContext(source, true); - context.LogEvent(TraceEventType.Attach, "[{0}]-->[{1}]", source.ThreadId, context.ThreadId); - _current = context; - } else { - _current = new TraceContext(); - } - } - - /// - /// Отсоединяет текущий контекст трассировки от потока, для дальнейшей его передачи другому потоку - /// . - /// - /// Контекст трассировки потока - /// - /// После отсоединения контекста трассировки от потока, при первом обращении к трассировке в этом - /// потоке будет создан новый контекст. - /// - public static TraceContext Detach() { - var context = Current; - context.LogEvent(TraceEventType.Detach, null); - _current = null; - return context; - } - - /// - /// Создает постоянную копию текущего контекста, данную копию можно хранить и использовать для передачи через - /// - /// Копия текущего контекста трассировки. - public static TraceContext Snapshot() { - return _current == null ? new TraceContext() : new TraceContext(_current,false); - } - - /// - /// Выполняет переданное действие в указанном контексте трассировки, по окончании восстанавливает предыдущий контекст трассировки потока. - /// - /// - public void Invoke(Action action) { - if (action == null) - throw new ArgumentNullException("action"); - var old = _current; - Fork(this); - try { - action(); - } finally { - if(_current != null) - _current.EndAllOperations(); - _current = old; - } - } - - /// - /// Текущая логическая операция. - /// - public LogicalOperation CurrentOperation { - get { - return m_currentOperation; - } - } - - /// - /// Операция ниже которой нельзя опускаться в стеке логических операций, т.е. она не может быть завершена в текущем контексте. - /// - public LogicalOperation BoundOperation { - get { - return m_bound; - } - } - - /// - /// Поток, в котором создан контекст трассировки. - /// - public int ThreadId { - get { - return m_threadId; - } - } - - /// - /// Начинает безымянную логическую операцию. - /// - public void StartLogicalOperation() { - StartLogicalOperation(null); - } - - /// - /// Начинает логическую операцию с указанным именем. Созданная операция будет добвалена в стек логических операций контекста, затем будет создано соответсвующее событие. - /// - /// Имя начинаемой операции. - public void StartLogicalOperation(string name) { - m_currentOperation = new LogicalOperation(name, m_currentOperation); - LogEvent(TraceEventType.OperationStarted, name); - } - - /// - /// Заканчивает логическую операцию начатую в текущем контексте. Операции, начатые в других контекстах не могут быть закончены в текущем контексте. - /// - /// - /// При вызове данного метода создается событие журнала трассировки, либо о завершении операции, либо об ошибки, поскольку данная операция - /// начата в другом контексте. - /// - public void EndLogicalOperation() { - if (m_bound == m_currentOperation) { - LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace"); - } else { - var op = m_currentOperation; - LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration); - m_currentOperation = m_currentOperation.Parent; - } - } - - /// - /// Создает копию контекста и возвращается на предыдущую операцию в текущем контексте, это позволяет начать операцию в одном потоке, а завершить - в другом. - /// - /// Контекст трассировки, который можно присоединить к другому потоку. - public TraceContext DetachLogicalOperation() { - if (m_bound == m_currentOperation) { - return new TraceContext(); - } else { - var detached = new TraceContext(this, true); - m_currentOperation = m_currentOperation.Parent; - return detached; - } - } - - public void BindLogicalOperationToPromise(IPromise promise) { - Safe.ArgumentNotNull(promise, "promise"); - - var ctx = DetachLogicalOperation(); - promise.Anyway(() => { - var old = _current; - TraceContext.Attach(ctx); - TraceContext.Current.EndLogicalOperation(); - _current = old; - }); - } - - /// - /// Заврешает все начатые в этом контексте операции - /// - public void EndAllOperations() { - while (m_bound != m_currentOperation) - EndLogicalOperation(); - } - - void LogEvent(TraceEventType type, string format, params object[] args) { - LogChannel.Default.LogEvent(this, TraceEvent.Create(type, format, args)); - } - } -} +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Implab.Diagnostics { + /// + /// Trace context is bound to the specific thread, each thread has it's own ThreadContext. + /// + /// + /// ThreadContext manages relations between logical operations and threads. + /// + public class TraceContext { + + [ThreadStatic] + static TraceContext _instance; + + OperationContext m_current = OperationContext.EMPTY; + readonly Stack m_stack = new Stack(); + readonly int m_threadId; + + public static TraceContext Instance { + get { + if (_instance == null) + _instance = new TraceContext(); + return _instance; + } + } + + public TraceContext() { + m_threadId = Thread.CurrentThread.ManagedThreadId; + } + + public int ThreadId { + get { return m_threadId; } + } + + public LogicalOperation CurrentOperation { + get { + return m_current.CurrentOperation; + } + } + + public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) { + // TODO Emit event + m_stack.Push(m_current); + m_current = new OperationContext(operation, takeOwnership); + } + + public void StartLogicalOperation(string name) { + m_current.BeginLogicalOperation(name); + } + + public void StartLogicalOperation() { + // TODO Emit Event + m_current.BeginLogicalOperation(String.Empty); + } + + public void EndLogicalOperation() { + // TODO Emit event + m_current.EndLogicalOperation(); + } + + public LogicalOperation DetachLogicalOperation() { + // TODO Emit event + return m_current.DetachLogicalOperation(); + } + + public void Leave() { + // TODO Emit event + if (m_stack.Count > 0) + m_current = m_stack.Pop(); + else { + TraceLog.TraceWarning("Attemtp to leave the last operation context"); + m_current = OperationContext.EMPTY; + } + } + } +} + diff --git a/Implab/Diagnostics/TraceLog.cs b/Implab/Diagnostics/TraceLog.cs --- a/Implab/Diagnostics/TraceLog.cs +++ b/Implab/Diagnostics/TraceLog.cs @@ -14,22 +14,17 @@ namespace Implab.Diagnostics { public static class TraceLog { [Conditional("TRACE")] public static void StartLogicalOperation() { - TraceContext.Current.StartLogicalOperation(); + TraceContext.Instance.StartLogicalOperation(); } [Conditional("TRACE")] public static void StartLogicalOperation(string name) { - TraceContext.Current.StartLogicalOperation(name); + TraceContext.Instance.StartLogicalOperation(name); } [Conditional("TRACE")] public static void EndLogicalOperation() { - TraceContext.Current.EndLogicalOperation(); - } - - [Conditional("TRACE")] - public static void BindLogicalOperationToPromise(IPromise promise) { - TraceContext.Current.BindLogicalOperationToPromise(promise); + TraceContext.Instance.EndLogicalOperation(); } [Conditional("TRACE")] diff --git a/Implab/Implab.csproj b/Implab/Implab.csproj --- a/Implab/Implab.csproj +++ b/Implab/Implab.csproj @@ -80,7 +80,6 @@ - @@ -141,6 +140,11 @@ + + + + + diff --git a/Implab/Parallels/ArrayTraits.cs b/Implab/Parallels/ArrayTraits.cs --- a/Implab/Parallels/ArrayTraits.cs +++ b/Implab/Parallels/ArrayTraits.cs @@ -12,7 +12,7 @@ namespace Implab.Parallels { readonly Action m_action; readonly TSrc[] m_source; readonly Promise m_promise = new Promise(); - readonly TraceContext m_traceContext; + readonly LogicalOperation m_logicalOperation; int m_pending; int m_next; @@ -23,7 +23,7 @@ namespace Implab.Parallels { Debug.Assert(source != null); Debug.Assert(action != null); - m_traceContext = TraceContext.Snapshot(); + m_logicalOperation = TraceContext.Instance.CurrentOperation; m_next = 0; m_source = source; m_pending = source.Length; @@ -41,8 +41,12 @@ namespace Implab.Parallels { } protected override void Worker() { - TraceContext.Fork(m_traceContext); - base.Worker(); + TraceContext.Instance.EnterLogicalOperation(m_logicalOperation, false); + try { + base.Worker(); + } finally { + TraceContext.Instance.Leave(); + } } protected override bool TryDequeue(out int unit) { @@ -67,7 +71,7 @@ namespace Implab.Parallels { readonly TSrc[] m_source; readonly TDst[] m_dest; readonly Promise m_promise = new Promise(); - readonly TraceContext m_traceContext; + readonly LogicalOperation m_logicalOperation; int m_pending; int m_next; @@ -83,7 +87,7 @@ namespace Implab.Parallels { m_dest = new TDst[source.Length]; m_pending = source.Length; m_transform = transform; - m_traceContext = TraceContext.Snapshot(); + m_logicalOperation = TraceContext.Instance.CurrentOperation; m_promise.Anyway(Dispose); @@ -97,13 +101,17 @@ namespace Implab.Parallels { } protected override void Worker() { - TraceContext.Fork(m_traceContext); - base.Worker(); + TraceContext.Instance.EnterLogicalOperation(m_logicalOperation,false); + try { + base.Worker(); + } finally { + TraceContext.Instance.Leave(); + } } protected override bool TryDequeue(out int unit) { unit = Interlocked.Increment(ref m_next) - 1; - return unit >= m_source.Length ? false : true; + return unit < m_source.Length; } protected override void InvokeUnit(int unit) { diff --git a/Implab/Parallels/AsyncPool.cs b/Implab/Parallels/AsyncPool.cs --- a/Implab/Parallels/AsyncPool.cs +++ b/Implab/Parallels/AsyncPool.cs @@ -14,15 +14,17 @@ namespace Implab.Parallels { public static IPromise Invoke(Func func) { var p = new Promise(); - var caller = TraceContext.Snapshot(); + var caller = TraceContext.Instance.CurrentOperation; ThreadPool.QueueUserWorkItem(param => { - TraceContext.Fork(caller); + TraceContext.Instance.EnterLogicalOperation(caller,false); try { p.Resolve(func()); } catch(Exception e) { p.Reject(e); - } + } finally { + TraceContext.Instance.Leave(); + } }); return p; @@ -31,14 +33,16 @@ namespace Implab.Parallels { public static IPromise InvokeNewThread(Func func) { var p = new Promise(); - var caller = TraceContext.Snapshot(); + var caller = TraceContext.Instance.CurrentOperation; var worker = new Thread(() => { - TraceContext.Fork(caller); + TraceContext.Instance.EnterLogicalOperation(caller,false); try { p.Resolve(func()); } catch (Exception e) { p.Reject(e); + } finally { + TraceContext.Instance.Leave(); } }); worker.IsBackground = true; @@ -51,15 +55,17 @@ namespace Implab.Parallels { public static IPromise InvokeNewThread(Action func) { var p = new Promise(); - var caller = TraceContext.Snapshot(); + var caller = TraceContext.Instance.CurrentOperation; var worker = new Thread(() => { - TraceContext.Fork(caller); + TraceContext.Instance.EnterLogicalOperation(caller,false); try { func(); p.Resolve(); } catch (Exception e) { p.Reject(e); + } finally { + TraceContext.Instance.Leave(); } }); worker.IsBackground = true; diff --git a/Implab/Parallels/DispatchPool.cs b/Implab/Parallels/DispatchPool.cs --- a/Implab/Parallels/DispatchPool.cs +++ b/Implab/Parallels/DispatchPool.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; -using System.Diagnostics; namespace Implab.Parallels { public abstract class DispatchPool : IDisposable { @@ -150,14 +146,13 @@ namespace Implab.Parallels { protected bool StartWorker() { if (AllocateThreadSlot()) { // slot successfully allocated - var worker = new Thread(this.Worker); + var worker = new Thread(Worker); worker.IsBackground = true; worker.Start(); return true; - } else { - return false; } + return false; } protected abstract void InvokeUnit(TUnit unit); diff --git a/Implab/Parallels/WorkerPool.cs b/Implab/Parallels/WorkerPool.cs --- a/Implab/Parallels/WorkerPool.cs +++ b/Implab/Parallels/WorkerPool.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using System.Diagnostics; using Implab.Diagnostics; @@ -12,29 +9,24 @@ namespace Implab.Parallels { MTQueue m_queue = new MTQueue(); int m_queueLength = 0; readonly int m_threshold = 1; - int m_workers = 0; public WorkerPool(int minThreads, int maxThreads, int threshold) : base(minThreads, maxThreads) { m_threshold = threshold; - m_workers = minThreads; InitPool(); } public WorkerPool(int minThreads, int maxThreads) : base(minThreads, maxThreads) { - m_workers = minThreads; InitPool(); } public WorkerPool(int threads) : base(threads) { - m_workers = threads; InitPool(); } - public WorkerPool() - : base() { + public WorkerPool() { InitPool(); } @@ -46,16 +38,17 @@ namespace Implab.Parallels { var promise = new Promise(); - var caller = TraceContext.Snapshot(); + var lop = TraceContext.Instance.CurrentOperation; EnqueueTask(delegate() { - caller.Invoke(delegate() { - try { - promise.Resolve(task()); - } catch (Exception e) { - promise.Reject(e); - } - }); + TraceContext.Instance.EnterLogicalOperation(lop, false); + try { + promise.Resolve(task()); + } catch (Exception e) { + promise.Reject(e); + } finally { + TraceContext.Instance.Leave(); + } }); return promise;