##// END OF EJS Templates
rewritten tracing
cin -
r92:4c0e5ef99986 v2
parent child
Show More
@@ -0,0 +1,15
1 namespace Implab.Diagnostics {
2 public static class Extensions {
3 public static IPromise<T> EndLogicalOperation<T>(this IPromise<T> promise) {
4 Safe.ArgumentNotNull(promise, "promise");
5 var op = TraceContext.Instance.DetachLogicalOperation();
6
7 return promise.Anyway(() => {
8 TraceContext.Instance.EnterLogicalOperation(op,true);
9 TraceLog.EndLogicalOperation();
10 TraceContext.Instance.Leave();
11 });
12 }
13 }
14 }
15
@@ -0,0 +1,24
1 using System;
2
3 namespace Implab.Diagnostics {
4 public class LogEventArgs : EventArgs {
5 public int ThreadId {
6 get;
7 private set;
8 }
9 public LogicalOperation Operation {
10 get;
11 private set;
12 }
13 public int OperationTimeOffset {
14 get;
15 private set;
16 }
17 public LogEventArgs(int threadId, LogicalOperation operation, int timeOffset) {
18 ThreadId = threadId;
19 Operation = operation;
20 OperationTimeOffset = timeOffset;
21 }
22 }
23 }
24
@@ -0,0 +1,13
1 namespace Implab.Diagnostics {
2 public class LogEventArgs<TEvent> : LogEventArgs {
3 public TEvent Value {
4 get;
5 private set;
6 }
7
8 public LogEventArgs(TEvent value, int threadId, LogicalOperation operation, int timeOffset) : base(threadId, operation, timeOffset) {
9 Value = value;
10 }
11 }
12 }
13
@@ -0,0 +1,49
1 namespace Implab.Diagnostics {
2 struct OperationContext {
3 readonly LogicalOperation m_initial;
4 public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false);
5 LogicalOperation m_current;
6 readonly bool m_ownership;
7
8 public OperationContext(LogicalOperation operation, bool ownership) {
9 Safe.ArgumentNotNull(operation, "operation");
10
11 m_initial = operation;
12 m_current = operation;
13 m_ownership = ownership;
14 }
15
16 public LogicalOperation CurrentOperation {
17 get { return m_current; }
18 }
19
20 public void BeginLogicalOperation(string name) {
21 m_current = new LogicalOperation(name, m_current);
22 }
23
24 public LogicalOperation DetachLogicalOperation() {
25 var detached = m_current;
26 if (m_current != LogicalOperation.EMPTY) {
27 if (m_current != m_initial)
28 m_current = m_current.Parent;
29 else if (m_ownership)
30 m_current = LogicalOperation.EMPTY;
31 else
32 detached = LogicalOperation.EMPTY;
33 }
34 TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context");
35 return detached;
36 }
37
38 public void EndLogicalOperation() {
39 if (m_current != m_initial) {
40 m_current = m_current.Parent;
41 } else if (m_current != null && m_ownership) {
42 m_current = null;
43 } else {
44 TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context");
45 }
46 }
47 }
48 }
49
@@ -107,11 +107,11 namespace Implab.Diagnostics.Interactive
107 base.Dispose(disposing);
107 base.Dispose(disposing);
108 }
108 }
109
109
110 protected override void WriteEntry(TraceContext context, EventText text, string channel) {
110 protected override void WriteEntry(LogEventArgs args, EventText text, string channel) {
111 var item = new TraceViewItem {
111 var item = new TraceViewItem {
112 Indent = text.indent,
112 Indent = text.indent,
113 Message = text.content,
113 Message = text.content,
114 Thread = context.ThreadId,
114 Thread = args.ThreadId,
115 Channel = channel,
115 Channel = channel,
116 Timestamp = Environment.TickCount
116 Timestamp = Environment.TickCount
117 };
117 };
@@ -18,16 +18,16 namespace Implab.Diagnostics {
18
18
19 }
19 }
20
20
21 protected override void WriteEntry(TraceContext context, EventText text, string channel) {
21 protected override void WriteEntry(LogEventArgs args, EventText text, string channel) {
22 var msg = new StringBuilder();
22 var msg = new StringBuilder();
23
23
24 for (int i = 0; i < text.indent; i++)
24 for (int i = 0; i < text.indent; i++)
25 msg.Append(" ");
25 msg.Append(" ");
26 msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content);
26 msg.AppendFormat("[{0}]:{1}: {2}", args.ThreadId, channel, text.content);
27
27
28 lock (_consoleLock) {
28 lock (_consoleLock) {
29 Console.ForegroundColor = (ConsoleColor)(context.ThreadId % 15 + 1);
29 Console.ForegroundColor = (ConsoleColor)(args.ThreadId % 15 + 1);
30 Console.WriteLine(msg.ToString());
30 Console.WriteLine(msg);
31 }
31 }
32 }
32 }
33 }
33 }
@@ -1,10 +1,5
1 using System;
1 namespace Implab.Diagnostics {
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab.Diagnostics {
7 public interface IEventTextFormatter<in TEvent> {
2 public interface IEventTextFormatter<in TEvent> {
8 EventText Format(TraceContext context, TEvent data);
3 EventText Format(LogEventArgs args, TEvent data);
9 }
4 }
10 }
5 }
@@ -27,7 +27,7 namespace Implab.Diagnostics {
27 /// <summary>
27 /// <summary>
28 /// Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ появлСниС Π½ΠΎΠ²ΠΎΠΉ записи Π² ΠΆΡƒΡ€Π½Π°Π»Π΅, Π½Π° это событиС ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΠΈ.
28 /// Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ появлСниС Π½ΠΎΠ²ΠΎΠΉ записи Π² ΠΆΡƒΡ€Π½Π°Π»Π΅, Π½Π° это событиС ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΠΈ.
29 /// </summary>
29 /// </summary>
30 public event EventHandler<ValueEventArgs<TEvent>> Events;
30 public event EventHandler<LogEventArgs<TEvent>> Events;
31
31
32 /// <summary>
32 /// <summary>
33 /// Имя ΠΊΠ°Π½Π°Π»Π°, ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для отобраТСния Π² ΠΆΡƒΡ€Π½Π°Π»Π΅
33 /// Имя ΠΊΠ°Π½Π°Π»Π°, ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для отобраТСния Π² ΠΆΡƒΡ€Π½Π°Π»Π΅
@@ -63,19 +63,18 namespace Implab.Diagnostics {
63 /// </remarks>
63 /// </remarks>
64 public void LogEvent(TEvent data) {
64 public void LogEvent(TEvent data) {
65 var t = Events;
65 var t = Events;
66 if (t!= null)
66 if (t != null) {
67 t(TraceContext.Current,new ValueEventArgs<TEvent>(data));
67 var traceContext = TraceContext.Instance;
68 }
68 t(
69
69 this,
70 /// <summary>
70 new LogEventArgs<TEvent>(
71 /// ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ запись ΠΆΡƒΡ€Π½Π°Π»Π° Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ°Π½Π°Π» подписчикам.
71 data,
72 /// </summary>
72 traceContext.ThreadId,
73 /// <param name="data">Π—Π°ΠΏΠΈΡΡŒ ΠΆΡƒΡ€Π½Π°Π»Π°.</param>
73 traceContext.CurrentOperation,
74 /// <param name="context">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рассылаСтся сообщСниС/</param>
74 traceContext.CurrentOperation.Duration
75 public void LogEvent(TraceContext context,TEvent data) {
75 )
76 var t = Events;
76 );
77 if (t != null)
78 t(context, new ValueEventArgs<TEvent>(data));
79 }
77 }
80 }
78 }
81 }
79 }
80 }
@@ -1,11 +1,9
1 using System;
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
2
7 namespace Implab.Diagnostics {
3 namespace Implab.Diagnostics {
8 public class LogicalOperation {
4 public class LogicalOperation {
5 public static readonly LogicalOperation EMPTY = new LogicalOperation("__EMPTY__", null);
6
9 readonly LogicalOperation m_parent;
7 readonly LogicalOperation m_parent;
10 readonly string m_name;
8 readonly string m_name;
11 readonly int m_level;
9 readonly int m_level;
@@ -1,7 +1,5
1 using System;
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
2 using System.IO;
4 using System.Linq;
5 using System.Text;
3 using System.Text;
6
4
7 namespace Implab.Diagnostics {
5 namespace Implab.Diagnostics {
@@ -16,16 +14,16 namespace Implab.Diagnostics {
16 Register(this);
14 Register(this);
17 }
15 }
18
16
19 protected override void WriteEntry(TraceContext context, EventText text, string channel) {
17 protected override void WriteEntry(LogEventArgs args, EventText text, string channel) {
20 var msg = new StringBuilder();
18 var msg = new StringBuilder();
21 for (int i = 0; i < text.indent; i++)
19 for (int i = 0; i < text.indent; i++)
22 msg.Append(" ");
20 msg.Append(" ");
23 msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content);
21 msg.AppendFormat("[{0}]:{1}: {2}", args.ThreadId, channel, text.content);
24
22
25 lock (m_textWriter) {
23 lock (m_textWriter) {
26 if (!IsDisposed) {
24 if (!IsDisposed) {
27 // Ρ‚ΡƒΡ‚ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ Π΅Ρ‰Π΅ Π½Π΅ освобоТдСн m_textWriter
25 // Ρ‚ΡƒΡ‚ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ Π΅Ρ‰Π΅ Π½Π΅ освобоТдСн m_textWriter
28 m_textWriter.WriteLine(msg.ToString());
26 m_textWriter.WriteLine(msg);
29 m_textWriter.Flush();
27 m_textWriter.Flush();
30 }
28 }
31 }
29 }
@@ -13,7 +13,7 namespace Implab.Diagnostics {
13 protected TextListenerBase(bool global) {
13 protected TextListenerBase(bool global) {
14 Register(this);
14 Register(this);
15 if (!global) {
15 if (!global) {
16 m_boundOperation = TraceContext.Current.CurrentOperation;
16 m_boundOperation = TraceContext.Instance.CurrentOperation;
17 m_baseIndent = Math.Max(0, m_boundOperation.Level - 1);
17 m_baseIndent = Math.Max(0, m_boundOperation.Level - 1);
18 }
18 }
19 }
19 }
@@ -38,13 +38,12 namespace Implab.Diagnostics {
38 var formatter = GetService<IEventTextFormatter<TEvent>>();
38 var formatter = GetService<IEventTextFormatter<TEvent>>();
39 var channelName = channel.Name;
39 var channelName = channel.Name;
40
40
41 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => {
41 EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => {
42 TraceContext context = (TraceContext)sender;
42 var text = formatter.Format(args, args.Value);
43 var text = formatter.Format(context, args.Value);
44 text.indent -= m_baseIndent;
43 text.indent -= m_baseIndent;
45
44
46 if (IsRelated(context.CurrentOperation))
45 if (IsRelated(args.Operation))
47 WriteEntry(context, text, channelName);
46 WriteEntry(args, text, channelName);
48 };
47 };
49
48
50 if (m_subscriptions.ContainsKey(channel))
49 if (m_subscriptions.ContainsKey(channel))
@@ -97,19 +96,19 namespace Implab.Diagnostics {
97 /// Π”Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒΡΡ ΠΈΠ· Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ситуация, ΠΊΠΎΠ³Π΄Π°
96 /// Π”Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒΡΡ ΠΈΠ· Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Π° ситуация, ΠΊΠΎΠ³Π΄Π°
98 /// Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся ΡƒΠΆΠ΅ послС освобоТдСния ΠΎΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ <see cref="Dispose()"/>.
97 /// Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся ΡƒΠΆΠ΅ послС освобоТдСния ΠΎΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ <see cref="Dispose()"/>.
99 /// </remarks>
98 /// </remarks>
100 /// <param name="context">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки.</param>
101 /// <param name="text">ВСкст сообщСния.</param>
99 /// <param name="text">ВСкст сообщСния.</param>
102 protected abstract void WriteEntry(TraceContext context, EventText text, string channel);
100 /// <param name = "channel"></param>
101 protected abstract void WriteEntry(LogEventArgs args, EventText text, string channel);
103
102
104 public EventText Format(TraceContext context, object data) {
103 public EventText Format(LogEventArgs args, object data) {
105 return new EventText {
104 return new EventText {
106 indent = context.CurrentOperation.Level,
105 indent = args.Operation.Level,
107 content = data.ToString()
106 content = data.ToString()
108 };
107 };
109 }
108 }
110
109
111 public EventText Format(TraceContext context, TraceEvent data) {
110 public EventText Format(LogEventArgs args, TraceEvent data) {
112 var level = context.CurrentOperation.Level;
111 var level = args.Operation.Level;
113 if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted)
112 if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted)
114 level--;
113 level--;
115
114
@@ -1,238 +1,79
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
3 using System.Threading;
6 using System.Threading.Tasks;
7
4
8 namespace Implab.Diagnostics {
5 namespace Implab.Diagnostics {
9 /// <summary>
6 /// <summary>
10 /// ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки, привязываСтся ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΈ содСрТит Π² сСбС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ стСкС логичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.
7 /// Trace context is bound to the specific thread, each thread has it's own ThreadContext.
11 /// </summary>
8 /// </summary>
12 /// <remarks>
9 /// <remarks>
13 /// ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки пСрСдаСтся ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΡΠΌ событий для опрСдСлСния мСста, Π³Π΄Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΎ событиС.
10 /// ThreadContext manages relations between logical operations and threads.
14 /// </remarks>
11 /// </remarks>
15 public class TraceContext {
12 public class TraceContext {
16 LogicalOperation m_currentOperation;
17 readonly LogicalOperation m_bound;
18 readonly int m_threadId;
19
13
20 [ThreadStatic]
14 [ThreadStatic]
21 static TraceContext _current;
15 static TraceContext _instance;
22
23 /// <summary>
24 /// Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ контСкст трассировки для ΠΏΠΎΡ‚ΠΎΠΊΠ°, создаСтся астоматичСски ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ.
25 /// </summary>
26 public static TraceContext Current {
27 get {
28 if (_current == null) {
29 _current = new TraceContext();
30 _current.LogEvent(TraceEventType.Created,"[{0}]", _current.ThreadId);
31 }
32 return _current;
33 }
34 }
35
16
36 TraceContext(TraceContext context)
17 OperationContext m_current = OperationContext.EMPTY;
37 : this(context, false) {
18 readonly Stack<OperationContext> m_stack = new Stack<OperationContext>();
38 }
19 readonly int m_threadId;
39
40 TraceContext(TraceContext context, bool attach) {
41 if (context == null)
42 throw new ArgumentNullException("context");
43
44 m_currentOperation = context.CurrentOperation;
45 m_bound = attach ? context.BoundOperation : context.CurrentOperation;
46 m_threadId = Thread.CurrentThread.ManagedThreadId;
47 }
48
49 TraceContext() {
50 m_currentOperation = new LogicalOperation();
51 m_bound = m_currentOperation;
52 m_threadId = Thread.CurrentThread.ManagedThreadId;
53 }
54
20
55 /// <summary>
21 public static TraceContext Instance {
56 /// ΠŸΡ€ΠΈ нСобходимости ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ состояниС контСкста трассивровки Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ.
22 get {
57 /// </summary>
23 if (_instance == null)
58 /// <param name="from">Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ контСкст трассировки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ пСрСдаСтся.</param>
24 _instance = new TraceContext();
59 /// <remarks>
25 return _instance;
60 /// <para>
61 /// ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ происходит Π·Π° счСт создания Π½ΠΎΠ²ΠΎΠ³ΠΎ контСкста трассировки ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ Π΅Π³ΠΎ
62 /// состояния ΠΈΠ· ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ контСкста. ΠŸΡ€ΠΈ этом копируСтся стСк ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΎΠ΄Π½Π°ΠΊΠΎ Π² Π½ΠΎΠ²ΠΎΠΌ
63 /// контСкстС Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ логичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Ρ‹.
64 /// </para>
65 /// <para>
66 /// Если ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° состояния ΡΠΎΡΡ‚ΠΎΡΠ»Π°ΡΡŒ, Ρ‚ΠΎ вызываСтся событиС трассировки <see cref="TraceEventType.Fork"/>.
67 /// </para>
68 /// </remarks>
69 public static void Fork(TraceContext from) {
70 if (_current == from)
71 return;
72 if (from != null) {
73 var context = new TraceContext(from);
74 context.LogEvent(TraceEventType.Fork, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId);
75 _current = context;
76 } else {
77 _current = new TraceContext();
78 }
79 }
80
81 /// <summary>
82 /// Π—Π°Π΄Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ контСкст, Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅
83 /// логичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС.
84 /// </summary>
85 /// <param name="source"></param>
86 public static void Attach(TraceContext source) {
87 if (_current == source)
88 return;
89 if (source != null) {
90 var context = new TraceContext(source, true);
91 context.LogEvent(TraceEventType.Attach, "[{0}]-->[{1}]", source.ThreadId, context.ThreadId);
92 _current = context;
93 } else {
94 _current = new TraceContext();
95 }
26 }
96 }
27 }
97
28
98 /// <summary>
29 public TraceContext() {
99 /// ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ контСкст трассировки ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠ°, для дальнСйшСй Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ
30 m_threadId = Thread.CurrentThread.ManagedThreadId;
100 /// <see cref="Attach(TraceContext)"/>.
101 /// </summary>
102 /// <returns>ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки ΠΏΠΎΡ‚ΠΎΠΊΠ°</returns>
103 /// <remarks>
104 /// ПослС отсоСдинСния контСкста трассировки ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ трассировкС Π² этом
105 /// ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ создан Π½ΠΎΠ²Ρ‹ΠΉ контСкст.
106 /// </remarks>
107 public static TraceContext Detach() {
108 var context = Current;
109 context.LogEvent(TraceEventType.Detach, null);
110 _current = null;
111 return context;
112 }
113
114 /// <summary>
115 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ копию Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста, Π΄Π°Π½Π½ΡƒΡŽ копию ΠΌΠΎΠΆΠ½ΠΎ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ‡Π΅Ρ€Π΅Π· <see cref="Fork(TraceContext)"/>
116 /// </summary>
117 /// <returns>Копия Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста трассировки.</returns>
118 public static TraceContext Snapshot() {
119 return _current == null ? new TraceContext() : new TraceContext(_current,false);
120 }
31 }
121
32
122 /// <summary>
33 public int ThreadId {
123 /// ВыполняСт ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ΅ дСйствиС Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ контСкстС трассировки, ΠΏΠΎ ΠΎΠΊΠΎΠ½Ρ‡Π°Π½ΠΈΠΈ восстанавливаСт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ контСкст трассировки ΠΏΠΎΡ‚ΠΎΠΊΠ°.
34 get { return m_threadId; }
124 /// </summary>
125 /// <param name="action"></param>
126 public void Invoke(Action action) {
127 if (action == null)
128 throw new ArgumentNullException("action");
129 var old = _current;
130 Fork(this);
131 try {
132 action();
133 } finally {
134 if(_current != null)
135 _current.EndAllOperations();
136 _current = old;
137 }
138 }
35 }
139
36
140 /// <summary>
141 /// ВСкущая логичСская опСрация.
142 /// </summary>
143 public LogicalOperation CurrentOperation {
37 public LogicalOperation CurrentOperation {
144 get {
38 get {
145 return m_currentOperation;
39 return m_current.CurrentOperation;
146 }
147 }
148
149 /// <summary>
150 /// ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ Π½ΠΈΠΆΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ нСльзя ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ Π² стСкС логичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Ρ‚.Π΅. ΠΎΠ½Π° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС.
151 /// </summary>
152 public LogicalOperation BoundOperation {
153 get {
154 return m_bound;
155 }
156 }
157
158 /// <summary>
159 /// ΠŸΠΎΡ‚ΠΎΠΊ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ создан контСкст трассировки.
160 /// </summary>
161 public int ThreadId {
162 get {
163 return m_threadId;
164 }
40 }
165 }
41 }
166
42
167 /// <summary>
43 public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) {
168 /// НачинаСт Π±Π΅Π·Ρ‹ΠΌΡΠ½Π½ΡƒΡŽ Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ.
44 // TODO Emit event
169 /// </summary>
45 m_stack.Push(m_current);
46 m_current = new OperationContext(operation, takeOwnership);
47 }
48
49 public void StartLogicalOperation(string name) {
50 m_current.BeginLogicalOperation(name);
51 }
52
170 public void StartLogicalOperation() {
53 public void StartLogicalOperation() {
171 StartLogicalOperation(null);
54 // TODO Emit Event
55 m_current.BeginLogicalOperation(String.Empty);
172 }
56 }
173
57
174 /// <summary>
58 public void EndLogicalOperation() {
175 /// НачинаСт Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ. Бозданная опСрация Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π²Π°Π»Π΅Π½Π° Π² стСк логичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ контСкста, Π·Π°Ρ‚Π΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ создано ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΡƒΡŽΡ‰Π΅Π΅ событиС.
59 // TODO Emit event
176 /// </summary>
60 m_current.EndLogicalOperation();
177 /// <param name="name">Имя Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.</param>
61 }
178 public void StartLogicalOperation(string name) {
62
179 m_currentOperation = new LogicalOperation(name, m_currentOperation);
63 public LogicalOperation DetachLogicalOperation() {
180 LogEvent(TraceEventType.OperationStarted, name);
64 // TODO Emit event
65 return m_current.DetachLogicalOperation();
181 }
66 }
182
67
183 /// <summary>
68 public void Leave() {
184 /// Π—Π°ΠΊΠ°Π½Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π»ΠΎΠ³ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π½Π°Ρ‡Π°Ρ‚ΡƒΡŽ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… контСкстах Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Ρ‹ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС.
69 // TODO Emit event
185 /// </summary>
70 if (m_stack.Count > 0)
186 /// <remarks>
71 m_current = m_stack.Pop();
187 /// ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° создаСтся событиС ΠΆΡƒΡ€Π½Π°Π»Π° трассировки, Π»ΠΈΠ±ΠΎ ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Π»ΠΈΠ±ΠΎ ΠΎΠ± ошибки, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ данная опСрация
72 else {
188 /// Π½Π°Ρ‡Π°Ρ‚Π° Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ контСкстС.
73 TraceLog.TraceWarning("Attemtp to leave the last operation context");
189 /// </remarks>
74 m_current = OperationContext.EMPTY;
190 public void EndLogicalOperation() {
75 }
191 if (m_bound == m_currentOperation) {
76 }
192 LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace");
193 } else {
194 var op = m_currentOperation;
195 LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration);
196 m_currentOperation = m_currentOperation.Parent;
197 }
77 }
198 }
78 }
199
79
200 /// <summary>
201 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ копию контСкста ΠΈ возвращаСтся Π½Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ контСкстС, это позволяСт Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅, Π° Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ - Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ.
202 /// </summary>
203 /// <returns>ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ.</returns>
204 public TraceContext DetachLogicalOperation() {
205 if (m_bound == m_currentOperation) {
206 return new TraceContext();
207 } else {
208 var detached = new TraceContext(this, true);
209 m_currentOperation = m_currentOperation.Parent;
210 return detached;
211 }
212 }
213
214 public void BindLogicalOperationToPromise(IPromise promise) {
215 Safe.ArgumentNotNull(promise, "promise");
216
217 var ctx = DetachLogicalOperation();
218 promise.Anyway(() => {
219 var old = _current;
220 TraceContext.Attach(ctx);
221 TraceContext.Current.EndLogicalOperation();
222 _current = old;
223 });
224 }
225
226 /// <summary>
227 /// Π—Π°Π²Ρ€Π΅ΡˆΠ°Π΅Ρ‚ всС Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ Π² этом контСкстС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ
228 /// </summary>
229 public void EndAllOperations() {
230 while (m_bound != m_currentOperation)
231 EndLogicalOperation();
232 }
233
234 void LogEvent(TraceEventType type, string format, params object[] args) {
235 LogChannel<TraceEvent>.Default.LogEvent(this, TraceEvent.Create(type, format, args));
236 }
237 }
238 }
@@ -14,22 +14,17 namespace Implab.Diagnostics {
14 public static class TraceLog {
14 public static class TraceLog {
15 [Conditional("TRACE")]
15 [Conditional("TRACE")]
16 public static void StartLogicalOperation() {
16 public static void StartLogicalOperation() {
17 TraceContext.Current.StartLogicalOperation();
17 TraceContext.Instance.StartLogicalOperation();
18 }
18 }
19
19
20 [Conditional("TRACE")]
20 [Conditional("TRACE")]
21 public static void StartLogicalOperation(string name) {
21 public static void StartLogicalOperation(string name) {
22 TraceContext.Current.StartLogicalOperation(name);
22 TraceContext.Instance.StartLogicalOperation(name);
23 }
23 }
24
24
25 [Conditional("TRACE")]
25 [Conditional("TRACE")]
26 public static void EndLogicalOperation() {
26 public static void EndLogicalOperation() {
27 TraceContext.Current.EndLogicalOperation();
27 TraceContext.Instance.EndLogicalOperation();
28 }
29
30 [Conditional("TRACE")]
31 public static void BindLogicalOperationToPromise(IPromise promise) {
32 TraceContext.Current.BindLogicalOperationToPromise(promise);
33 }
28 }
34
29
35 [Conditional("TRACE")]
30 [Conditional("TRACE")]
@@ -80,7 +80,6
80 <Compile Include="Diagnostics\TextFileListener.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
81 <Compile Include="Diagnostics\TextListenerBase.cs" />
81 <Compile Include="Diagnostics\TextListenerBase.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
83 <Compile Include="Diagnostics\TraceContext.cs" />
84 <Compile Include="Diagnostics\TraceEvent.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
85 <Compile Include="Diagnostics\TraceEventType.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
86 <Compile Include="Disposable.cs" />
85 <Compile Include="Disposable.cs" />
@@ -141,6 +140,11
141 <Compile Include="TransientPromiseException.cs" />
140 <Compile Include="TransientPromiseException.cs" />
142 <Compile Include="SyncContextPromise.cs" />
141 <Compile Include="SyncContextPromise.cs" />
143 <Compile Include="ObjectPool.cs" />
142 <Compile Include="ObjectPool.cs" />
143 <Compile Include="Diagnostics\OperationContext.cs" />
144 <Compile Include="Diagnostics\TraceContext.cs" />
145 <Compile Include="Diagnostics\LogEventArgs.cs" />
146 <Compile Include="Diagnostics\LogEventArgsT.cs" />
147 <Compile Include="Diagnostics\Extensions.cs" />
144 </ItemGroup>
148 </ItemGroup>
145 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
149 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
146 <ItemGroup />
150 <ItemGroup />
@@ -12,7 +12,7 namespace Implab.Parallels {
12 readonly Action<TSrc> m_action;
12 readonly Action<TSrc> m_action;
13 readonly TSrc[] m_source;
13 readonly TSrc[] m_source;
14 readonly Promise<int> m_promise = new Promise<int>();
14 readonly Promise<int> m_promise = new Promise<int>();
15 readonly TraceContext m_traceContext;
15 readonly LogicalOperation m_logicalOperation;
16
16
17 int m_pending;
17 int m_pending;
18 int m_next;
18 int m_next;
@@ -23,7 +23,7 namespace Implab.Parallels {
23 Debug.Assert(source != null);
23 Debug.Assert(source != null);
24 Debug.Assert(action != null);
24 Debug.Assert(action != null);
25
25
26 m_traceContext = TraceContext.Snapshot();
26 m_logicalOperation = TraceContext.Instance.CurrentOperation;
27 m_next = 0;
27 m_next = 0;
28 m_source = source;
28 m_source = source;
29 m_pending = source.Length;
29 m_pending = source.Length;
@@ -41,8 +41,12 namespace Implab.Parallels {
41 }
41 }
42
42
43 protected override void Worker() {
43 protected override void Worker() {
44 TraceContext.Fork(m_traceContext);
44 TraceContext.Instance.EnterLogicalOperation(m_logicalOperation, false);
45 try {
45 base.Worker();
46 base.Worker();
47 } finally {
48 TraceContext.Instance.Leave();
49 }
46 }
50 }
47
51
48 protected override bool TryDequeue(out int unit) {
52 protected override bool TryDequeue(out int unit) {
@@ -67,7 +71,7 namespace Implab.Parallels {
67 readonly TSrc[] m_source;
71 readonly TSrc[] m_source;
68 readonly TDst[] m_dest;
72 readonly TDst[] m_dest;
69 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
73 readonly Promise<TDst[]> m_promise = new Promise<TDst[]>();
70 readonly TraceContext m_traceContext;
74 readonly LogicalOperation m_logicalOperation;
71
75
72 int m_pending;
76 int m_pending;
73 int m_next;
77 int m_next;
@@ -83,7 +87,7 namespace Implab.Parallels {
83 m_dest = new TDst[source.Length];
87 m_dest = new TDst[source.Length];
84 m_pending = source.Length;
88 m_pending = source.Length;
85 m_transform = transform;
89 m_transform = transform;
86 m_traceContext = TraceContext.Snapshot();
90 m_logicalOperation = TraceContext.Instance.CurrentOperation;
87
91
88 m_promise.Anyway(Dispose);
92 m_promise.Anyway(Dispose);
89
93
@@ -97,13 +101,17 namespace Implab.Parallels {
97 }
101 }
98
102
99 protected override void Worker() {
103 protected override void Worker() {
100 TraceContext.Fork(m_traceContext);
104 TraceContext.Instance.EnterLogicalOperation(m_logicalOperation,false);
105 try {
101 base.Worker();
106 base.Worker();
107 } finally {
108 TraceContext.Instance.Leave();
109 }
102 }
110 }
103
111
104 protected override bool TryDequeue(out int unit) {
112 protected override bool TryDequeue(out int unit) {
105 unit = Interlocked.Increment(ref m_next) - 1;
113 unit = Interlocked.Increment(ref m_next) - 1;
106 return unit >= m_source.Length ? false : true;
114 return unit < m_source.Length;
107 }
115 }
108
116
109 protected override void InvokeUnit(int unit) {
117 protected override void InvokeUnit(int unit) {
@@ -14,14 +14,16 namespace Implab.Parallels {
14
14
15 public static IPromise<T> Invoke<T>(Func<T> func) {
15 public static IPromise<T> Invoke<T>(Func<T> func) {
16 var p = new Promise<T>();
16 var p = new Promise<T>();
17 var caller = TraceContext.Snapshot();
17 var caller = TraceContext.Instance.CurrentOperation;
18
18
19 ThreadPool.QueueUserWorkItem(param => {
19 ThreadPool.QueueUserWorkItem(param => {
20 TraceContext.Fork(caller);
20 TraceContext.Instance.EnterLogicalOperation(caller,false);
21 try {
21 try {
22 p.Resolve(func());
22 p.Resolve(func());
23 } catch(Exception e) {
23 } catch(Exception e) {
24 p.Reject(e);
24 p.Reject(e);
25 } finally {
26 TraceContext.Instance.Leave();
25 }
27 }
26 });
28 });
27
29
@@ -31,14 +33,16 namespace Implab.Parallels {
31 public static IPromise<T> InvokeNewThread<T>(Func<T> func) {
33 public static IPromise<T> InvokeNewThread<T>(Func<T> func) {
32 var p = new Promise<T>();
34 var p = new Promise<T>();
33
35
34 var caller = TraceContext.Snapshot();
36 var caller = TraceContext.Instance.CurrentOperation;
35
37
36 var worker = new Thread(() => {
38 var worker = new Thread(() => {
37 TraceContext.Fork(caller);
39 TraceContext.Instance.EnterLogicalOperation(caller,false);
38 try {
40 try {
39 p.Resolve(func());
41 p.Resolve(func());
40 } catch (Exception e) {
42 } catch (Exception e) {
41 p.Reject(e);
43 p.Reject(e);
44 } finally {
45 TraceContext.Instance.Leave();
42 }
46 }
43 });
47 });
44 worker.IsBackground = true;
48 worker.IsBackground = true;
@@ -51,15 +55,17 namespace Implab.Parallels {
51 public static IPromise InvokeNewThread(Action func) {
55 public static IPromise InvokeNewThread(Action func) {
52 var p = new Promise<object>();
56 var p = new Promise<object>();
53
57
54 var caller = TraceContext.Snapshot();
58 var caller = TraceContext.Instance.CurrentOperation;
55
59
56 var worker = new Thread(() => {
60 var worker = new Thread(() => {
57 TraceContext.Fork(caller);
61 TraceContext.Instance.EnterLogicalOperation(caller,false);
58 try {
62 try {
59 func();
63 func();
60 p.Resolve();
64 p.Resolve();
61 } catch (Exception e) {
65 } catch (Exception e) {
62 p.Reject(e);
66 p.Reject(e);
67 } finally {
68 TraceContext.Instance.Leave();
63 }
69 }
64 });
70 });
65 worker.IsBackground = true;
71 worker.IsBackground = true;
@@ -1,9 +1,5
1 using System;
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
2 using System.Threading;
6 using System.Diagnostics;
7
3
8 namespace Implab.Parallels {
4 namespace Implab.Parallels {
9 public abstract class DispatchPool<TUnit> : IDisposable {
5 public abstract class DispatchPool<TUnit> : IDisposable {
@@ -150,15 +146,14 namespace Implab.Parallels {
150 protected bool StartWorker() {
146 protected bool StartWorker() {
151 if (AllocateThreadSlot()) {
147 if (AllocateThreadSlot()) {
152 // slot successfully allocated
148 // slot successfully allocated
153 var worker = new Thread(this.Worker);
149 var worker = new Thread(Worker);
154 worker.IsBackground = true;
150 worker.IsBackground = true;
155 worker.Start();
151 worker.Start();
156
152
157 return true;
153 return true;
158 } else {
154 }
159 return false;
155 return false;
160 }
156 }
161 }
162
157
163 protected abstract void InvokeUnit(TUnit unit);
158 protected abstract void InvokeUnit(TUnit unit);
164
159
@@ -1,7 +1,4
1 using System;
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
2 using System.Threading;
6 using System.Diagnostics;
3 using System.Diagnostics;
7 using Implab.Diagnostics;
4 using Implab.Diagnostics;
@@ -12,29 +9,24 namespace Implab.Parallels {
12 MTQueue<Action> m_queue = new MTQueue<Action>();
9 MTQueue<Action> m_queue = new MTQueue<Action>();
13 int m_queueLength = 0;
10 int m_queueLength = 0;
14 readonly int m_threshold = 1;
11 readonly int m_threshold = 1;
15 int m_workers = 0;
16
12
17 public WorkerPool(int minThreads, int maxThreads, int threshold)
13 public WorkerPool(int minThreads, int maxThreads, int threshold)
18 : base(minThreads, maxThreads) {
14 : base(minThreads, maxThreads) {
19 m_threshold = threshold;
15 m_threshold = threshold;
20 m_workers = minThreads;
21 InitPool();
16 InitPool();
22 }
17 }
23
18
24 public WorkerPool(int minThreads, int maxThreads) :
19 public WorkerPool(int minThreads, int maxThreads) :
25 base(minThreads, maxThreads) {
20 base(minThreads, maxThreads) {
26 m_workers = minThreads;
27 InitPool();
21 InitPool();
28 }
22 }
29
23
30 public WorkerPool(int threads)
24 public WorkerPool(int threads)
31 : base(threads) {
25 : base(threads) {
32 m_workers = threads;
33 InitPool();
26 InitPool();
34 }
27 }
35
28
36 public WorkerPool()
29 public WorkerPool() {
37 : base() {
38 InitPool();
30 InitPool();
39 }
31 }
40
32
@@ -46,17 +38,18 namespace Implab.Parallels {
46
38
47 var promise = new Promise<T>();
39 var promise = new Promise<T>();
48
40
49 var caller = TraceContext.Snapshot();
41 var lop = TraceContext.Instance.CurrentOperation;
50
42
51 EnqueueTask(delegate() {
43 EnqueueTask(delegate() {
52 caller.Invoke(delegate() {
44 TraceContext.Instance.EnterLogicalOperation(lop, false);
53 try {
45 try {
54 promise.Resolve(task());
46 promise.Resolve(task());
55 } catch (Exception e) {
47 } catch (Exception e) {
56 promise.Reject(e);
48 promise.Reject(e);
49 } finally {
50 TraceContext.Instance.Leave();
57 }
51 }
58 });
52 });
59 });
60
53
61 return promise;
54 return promise;
62 }
55 }
General Comments 0
You need to be logged in to leave comments. Login now