TraceContext.cs
83 lines
| 3.0 KiB
| text/x-csharp
|
CSharpLexer
cin
|
r92 | using System; | ||
using System.Collections.Generic; | ||||
using System.Threading; | ||||
namespace Implab.Diagnostics { | ||||
/// <summary> | ||||
/// Trace context is bound to the specific thread, each thread has it's own ThreadContext. | ||||
/// </summary> | ||||
/// <remarks> | ||||
/// ThreadContext manages relations between logical operations and threads. | ||||
/// </remarks> | ||||
public class TraceContext { | ||||
[ThreadStatic] | ||||
static TraceContext _instance; | ||||
OperationContext m_current = OperationContext.EMPTY; | ||||
readonly Stack<OperationContext> m_stack = new Stack<OperationContext>(); | ||||
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) { | ||||
cin
|
r94 | var prev = CurrentOperation; | ||
cin
|
r92 | m_stack.Push(m_current); | ||
m_current = new OperationContext(operation, takeOwnership); | ||||
cin
|
r94 | LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(takeOwnership ? TraceEventType.Attach : TraceEventType.Enter, String.Format("{0} -> {1}",prev.Name, operation.Name))); | ||
cin
|
r92 | } | ||
public void StartLogicalOperation(string name) { | ||||
m_current.BeginLogicalOperation(name); | ||||
cin
|
r93 | LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationStarted, String.Format("+{0}",CurrentOperation.Name))); | ||
cin
|
r92 | } | ||
public void StartLogicalOperation() { | ||||
cin
|
r93 | StartLogicalOperation(String.Empty); | ||
cin
|
r92 | } | ||
public void EndLogicalOperation() { | ||||
cin
|
r93 | LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.OperationCompleted, String.Format("-{0} : {1}ms",CurrentOperation.Name, CurrentOperation.Duration))); | ||
cin
|
r92 | m_current.EndLogicalOperation(); | ||
} | ||||
public LogicalOperation DetachLogicalOperation() { | ||||
cin
|
r94 | var prev = m_current.DetachLogicalOperation(); | ||
LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Detach, String.Format("{0} -> {1}",prev.Name, CurrentOperation.Name))); | ||||
return prev; | ||||
cin
|
r92 | } | ||
public void Leave() { | ||||
cin
|
r93 | if (m_stack.Count > 0) { | ||
m_current.Leave(); | ||||
cin
|
r94 | var prev = CurrentOperation; | ||
cin
|
r92 | m_current = m_stack.Pop(); | ||
cin
|
r94 | LogChannel<TraceEvent>.Default.LogEvent(new TraceEvent(TraceEventType.Leave, String.Format("{0} -> {1}", prev.Name, CurrentOperation.Name))); | ||
cin
|
r93 | } else { | ||
cin
|
r92 | TraceLog.TraceWarning("Attemtp to leave the last operation context"); | ||
m_current = OperationContext.EMPTY; | ||||
} | ||||
} | ||||
} | ||||
} | ||||