##// END OF EJS Templates
Interactive tracing...
cin -
r48:d9d794b61bb9 interactive logger
parent child
Show More
@@ -9,15 +9,14 using System.Windows.Forms;
9
9
10 namespace Implab.Diagnostics.Interactive
10 namespace Implab.Diagnostics.Interactive
11 {
11 {
12 public class InteractiveListener: Disposable
12 public class InteractiveListener: TextListenerBase
13 {
13 {
14 TraceForm m_form;
14 TraceForm m_form;
15
15
16 SynchronizationContext m_syncGuiThread;
16 SynchronizationContext m_syncGuiThread;
17 readonly Promise<object> m_guiStarted = new Promise<object>();
17
18
18 readonly IPromiseBase m_guiFinished;
19 readonly IPromiseBase m_guiFinished;
19 readonly Promise<object> m_guiStarted = new Promise<object>();
20
21 readonly IPromiseBase m_workerFinished = new Promise<object>();
20 readonly IPromiseBase m_workerFinished = new Promise<object>();
22
21
23 readonly MTQueue<TraceViewItem> m_queue = new MTQueue<TraceViewItem>();
22 readonly MTQueue<TraceViewItem> m_queue = new MTQueue<TraceViewItem>();
@@ -30,17 +29,19 namespace Implab.Diagnostics.Interactive
30 bool m_paused;
29 bool m_paused;
31 readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
30 readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
32
31
33 public InteractiveListener() {
32 public InteractiveListener(bool global) : base(global) {
34 m_guiFinished = AsyncPool.InvokeNewThread(() => {
33 m_guiFinished = AsyncPool.InvokeNewThread(GuiThread);
35 GuiThread();
34 m_workerFinished = AsyncPool.InvokeNewThread(QueueThread);
36 return 0;
37 });
38
35
39 m_guiStarted.Join();
36 m_guiStarted.Join();
40 }
37 }
41
38
42 void GuiThread() {
39 void GuiThread() {
43 m_form = new TraceForm(); // will create SynchronizationContext
40 m_form = new TraceForm(); // will create SynchronizationContext
41
42 m_form.PauseEvents += (s,a) => Pause();
43 m_form.ResumeEvents += (s, a) => Resume();
44
44 m_syncGuiThread = SynchronizationContext.Current;
45 m_syncGuiThread = SynchronizationContext.Current;
45 m_guiStarted.Resolve();
46 m_guiStarted.Resolve();
46 Application.Run();
47 Application.Run();
@@ -93,6 +94,8 namespace Implab.Diagnostics.Interactive
93 }
94 }
94
95
95 void Terminate() {
96 void Terminate() {
97 m_exitPending = true;
98 Resume();
96 m_syncGuiThread.Post(x => Application.ExitThread(), null);
99 m_syncGuiThread.Post(x => Application.ExitThread(), null);
97 }
100 }
98
101
@@ -103,5 +106,17 namespace Implab.Diagnostics.Interactive
103 }
106 }
104 base.Dispose(disposing);
107 base.Dispose(disposing);
105 }
108 }
109
110 protected override void WriteEntry(TraceContext context, EventText text, string channel) {
111 var item = new TraceViewItem {
112 Indent = text.indent,
113 Message = text.content,
114 Thread = context.ThreadId,
115 Channel = channel,
116 Timestamp = Environment.TickCount
117 };
118
119 Enqueue(item);
106 }
120 }
107 }
121 }
122 }
@@ -30,6 +30,7
30 this.eventsDataGrid = new System.Windows.Forms.DataGridView();
30 this.eventsDataGrid = new System.Windows.Forms.DataGridView();
31 this.traceViewItemBindingSource = new System.Windows.Forms.BindingSource(this.components);
31 this.traceViewItemBindingSource = new System.Windows.Forms.BindingSource(this.components);
32 this.threadDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
32 this.threadDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
33 this.Channel = new System.Windows.Forms.DataGridViewTextBoxColumn();
33 this.messageDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
34 this.messageDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
34 ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).BeginInit();
35 ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).BeginInit();
35 ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).BeginInit();
36 ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).BeginInit();
@@ -55,6 +56,7
55 this.eventsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
56 this.eventsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
56 this.eventsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
57 this.eventsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
57 this.threadDataGridViewTextBoxColumn,
58 this.threadDataGridViewTextBoxColumn,
59 this.Channel,
58 this.messageDataGridViewTextBoxColumn});
60 this.messageDataGridViewTextBoxColumn});
59 this.eventsDataGrid.DataSource = this.traceViewItemBindingSource;
61 this.eventsDataGrid.DataSource = this.traceViewItemBindingSource;
60 dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
62 dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
@@ -87,6 +89,15
87 this.threadDataGridViewTextBoxColumn.ReadOnly = true;
89 this.threadDataGridViewTextBoxColumn.ReadOnly = true;
88 this.threadDataGridViewTextBoxColumn.Width = 5;
90 this.threadDataGridViewTextBoxColumn.Width = 5;
89 //
91 //
92 // Channel
93 //
94 this.Channel.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
95 this.Channel.DataPropertyName = "Channel";
96 this.Channel.HeaderText = "Channel";
97 this.Channel.Name = "Channel";
98 this.Channel.ReadOnly = true;
99 this.Channel.Width = 79;
100 //
90 // messageDataGridViewTextBoxColumn
101 // messageDataGridViewTextBoxColumn
91 //
102 //
92 this.messageDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
103 this.messageDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
@@ -116,6 +127,7
116 private System.Windows.Forms.DataGridView eventsDataGrid;
127 private System.Windows.Forms.DataGridView eventsDataGrid;
117 private System.Windows.Forms.BindingSource traceViewItemBindingSource;
128 private System.Windows.Forms.BindingSource traceViewItemBindingSource;
118 private System.Windows.Forms.DataGridViewTextBoxColumn threadDataGridViewTextBoxColumn;
129 private System.Windows.Forms.DataGridViewTextBoxColumn threadDataGridViewTextBoxColumn;
130 private System.Windows.Forms.DataGridViewTextBoxColumn Channel;
119 private System.Windows.Forms.DataGridViewTextBoxColumn messageDataGridViewTextBoxColumn;
131 private System.Windows.Forms.DataGridViewTextBoxColumn messageDataGridViewTextBoxColumn;
120
132
121 }
133 }
@@ -13,9 +13,12 namespace Implab.Diagnostics.Interactive
13 readonly Dictionary<int, Color> m_threadColors = new Dictionary<int,Color>();
13 readonly Dictionary<int, Color> m_threadColors = new Dictionary<int,Color>();
14 readonly Random m_rand = new Random();
14 readonly Random m_rand = new Random();
15
15
16 public event EventHandler PauseEvents;
17
18 public event EventHandler ResumeEvents;
19
16 public TraceForm() {
20 public TraceForm() {
17 InitializeComponent();
21 InitializeComponent();
18
19 }
22 }
20
23
21 protected override void OnFormClosing(FormClosingEventArgs e) {
24 protected override void OnFormClosing(FormClosingEventArgs e) {
@@ -26,18 +29,9 namespace Implab.Diagnostics.Interactive
26 }
29 }
27 }
30 }
28
31
29 public void AddTraceEvent(int indent, int thread, string message) {
30 traceViewItemBindingSource.Add(new TraceViewItem {
31 Indent = indent,
32 Thread = thread,
33 Message = message,
34 Timestamp = Environment.TickCount
35 });
36
37 }
38
39 public void AddTraceEvent(TraceViewItem item) {
32 public void AddTraceEvent(TraceViewItem item) {
40 traceViewItemBindingSource.Add(item);
33 traceViewItemBindingSource.Add(item);
34 eventsDataGrid.FirstDisplayedScrollingRowIndex = eventsDataGrid.RowCount - 1;
41 }
35 }
42
36
43 Color GetThreadColor(int thread) {
37 Color GetThreadColor(int thread) {
@@ -51,6 +45,7 namespace Implab.Diagnostics.Interactive
51
45
52 private void eventsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
46 private void eventsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
53 var data = (TraceViewItem)traceViewItemBindingSource[e.RowIndex];
47 var data = (TraceViewItem)traceViewItemBindingSource[e.RowIndex];
48 if (e.ColumnIndex == messageDataGridViewTextBoxColumn.Index)
54 e.CellStyle.Padding = new Padding(data.Indent * 10,0,0,0);
49 e.CellStyle.Padding = new Padding(data.Indent * 10,0,0,0);
55 e.CellStyle.ForeColor = GetThreadColor(data.Thread);
50 e.CellStyle.ForeColor = GetThreadColor(data.Thread);
56 }
51 }
@@ -117,6 +117,9
117 <resheader name="writer">
117 <resheader name="writer">
118 <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
118 <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119 </resheader>
119 </resheader>
120 <metadata name="Channel.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
121 <value>True</value>
122 </metadata>
120 <metadata name="traceViewItemBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
123 <metadata name="traceViewItemBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
121 <value>17, 17</value>
124 <value>17, 17</value>
122 </metadata>
125 </metadata>
@@ -12,6 +12,7 namespace Implab.Diagnostics.Interactive
12 public int Timestamp { get; set; }
12 public int Timestamp { get; set; }
13 public int Indent { get; set; }
13 public int Indent { get; set; }
14 public int Thread { get; set; }
14 public int Thread { get; set; }
15 public string Channel { get; set; }
15
16
16 public string FormattedMessage {
17 public string FormattedMessage {
17 get {
18 get {
@@ -13,17 +13,17 namespace Implab.Diagnostics {
13
13
14 }
14 }
15
15
16 public ConsoleTraceListener(bool local)
16 public ConsoleTraceListener(bool global)
17 : base(local) {
17 : base(global) {
18
18
19 }
19 }
20
20
21 protected override void WriteEntry(TraceContext context, EventText text) {
21 protected override void WriteEntry(TraceContext context, 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}", context.ThreadId, text.content);
26 msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content);
27
27
28 lock (_consoleLock) {
28 lock (_consoleLock) {
29 Console.ForegroundColor = (ConsoleColor)(context.ThreadId % 15 + 1);
29 Console.ForegroundColor = (ConsoleColor)(context.ThreadId % 15 + 1);
@@ -4,23 +4,74 using System.Linq;
4 using System.Text;
4 using System.Text;
5
5
6 namespace Implab.Diagnostics {
6 namespace Implab.Diagnostics {
7 /// <summary>
8 /// Канал, Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΡŽΡ‚ΡΡ события ΠΆΡƒΡ€Π½Π°Π»Π°.
9 /// </summary>
10 /// <typeparam name="TEvent">Π’ΠΈΠΏ событий Π² ΠΊΠ°Π½Π°Π»Π΅</typeparam>
11 /// <remarks>
12 /// Бобытиями ΠΆΡƒΡ€Π½Π°Π»Π° ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ строки, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒΡΡ
13 /// информация, ΠΈΠ»ΠΈ структуры с Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΠΏΠΎΠ»Π΅ΠΉ, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΡ… Π²Π°ΠΆΠ½ΠΎΡΡ‚ΡŒ, тСкст ΠΈ Π΄Ρ€ΡƒΠ³ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ.
14 /// </remarks>
7 public class LogChannel<TEvent> {
15 public class LogChannel<TEvent> {
8 static LogChannel<TEvent> _default = new LogChannel<TEvent>();
16 static LogChannel<TEvent> _default = new LogChannel<TEvent>();
9
17
18 /// <summary>
19 /// Канал ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для событий Ρ‚ΠΈΠΏΠ° <typeparam name="TEvent"/>.
20 /// </summary>
10 public static LogChannel<TEvent> Default {
21 public static LogChannel<TEvent> Default {
11 get {
22 get {
12 return _default;
23 return _default;
13 }
24 }
14 }
25 }
15
26
27 /// <summary>
28 /// Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ появлСниС Π½ΠΎΠ²ΠΎΠΉ записи Π² ΠΆΡƒΡ€Π½Π°Π»Π΅, Π½Π° это событиС ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΠΈ.
29 /// </summary>
16 public event EventHandler<ValueEventArgs<TEvent>> Events;
30 public event EventHandler<ValueEventArgs<TEvent>> Events;
17
31
32 /// <summary>
33 /// Имя ΠΊΠ°Π½Π°Π»Π°, ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для отобраТСния Π² ΠΆΡƒΡ€Π½Π°Π»Π΅
34 /// </summary>
35 public string Name {
36 get;
37 private set;
38 }
39
40 /// <summary>
41 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ΠΆΡƒΡ€Π½Π°Π», имя Ρ‚ΠΈΠΏΠ° событий назначаСтся Π² ΠΊΠ°Ρ‡Π΅Ρ‚Π²Π΅ ΠΈΠΌΠ΅Π½ΠΈ ΠΊΠ°Π½Π°Π»Π°.
42 /// </summary>
43 public LogChannel()
44 : this(null) {
45 }
46
47 /// <summary>
48 /// Π‘ΠΎΠ΄Π°Π΅Ρ‚ ΠΊΠ°Π½Π°Π» с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ.
49 /// </summary>
50 /// <param name="name">Имя канала.</param>
51 public LogChannel(string name) {
52 if (String.IsNullOrEmpty(name))
53 name = typeof(TEvent).Name;
54 Name = name;
55 }
56
57 /// <summary>
58 /// ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ запись ΠΆΡƒΡ€Π½Π°Π»Π° Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ°Π½Π°Π» подписчикам.
59 /// </summary>
60 /// <param name="data">Π—Π°ΠΏΠΈΡΡŒ ΠΆΡƒΡ€Π½Π°Π»Π°.</param>
61 /// <remarks>
62 /// ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рассылаСтся сообщСниС опрСдСляСтся автоматичСски ΠΈΠ· Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.
63 /// </remarks>
18 public void LogEvent(TEvent data) {
64 public void LogEvent(TEvent data) {
19 var t = Events;
65 var t = Events;
20 if (t!= null)
66 if (t!= null)
21 t(TraceContext.Current,new ValueEventArgs<TEvent>(data));
67 t(TraceContext.Current,new ValueEventArgs<TEvent>(data));
22 }
68 }
23
69
70 /// <summary>
71 /// ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅Ρ‚ запись ΠΆΡƒΡ€Π½Π°Π»Π° Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ°Π½Π°Π» подписчикам.
72 /// </summary>
73 /// <param name="data">Π—Π°ΠΏΠΈΡΡŒ ΠΆΡƒΡ€Π½Π°Π»Π°.</param>
74 /// <param name="context">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рассылаСтся сообщСниС/</param>
24 public void LogEvent(TraceContext context,TEvent data) {
75 public void LogEvent(TraceContext context,TEvent data) {
25 var t = Events;
76 var t = Events;
26 if (t != null)
77 if (t != null)
@@ -8,18 +8,19 namespace Implab.Diagnostics {
8 public class TextFileListener: TextListenerBase {
8 public class TextFileListener: TextListenerBase {
9 readonly TextWriter m_textWriter;
9 readonly TextWriter m_textWriter;
10
10
11 public TextFileListener(string fileName, bool local) : base(local) {
11 public TextFileListener(string fileName, bool global)
12 : base(global) {
12 m_textWriter = File.CreateText(fileName);
13 m_textWriter = File.CreateText(fileName);
13
14
14 m_textWriter.WriteLine("LOG {0}", DateTime.Now);
15 m_textWriter.WriteLine("LOG {0}", DateTime.Now);
15 Register(this);
16 Register(this);
16 }
17 }
17
18
18 protected override void WriteEntry(TraceContext context, EventText text) {
19 protected override void WriteEntry(TraceContext context, EventText text, string channel) {
19 var msg = new StringBuilder();
20 var msg = new StringBuilder();
20 for (int i = 0; i < text.indent; i++)
21 for (int i = 0; i < text.indent; i++)
21 msg.Append(" ");
22 msg.Append(" ");
22 msg.AppendFormat("[{0}]: {1}", context.ThreadId, text.content);
23 msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content);
23
24
24 lock (m_textWriter) {
25 lock (m_textWriter) {
25 if (!IsDisposed) {
26 if (!IsDisposed) {
@@ -10,9 +10,9 namespace Implab.Diagnostics {
10 readonly LogicalOperation m_boundOperation;
10 readonly LogicalOperation m_boundOperation;
11 readonly int m_baseIndent;
11 readonly int m_baseIndent;
12
12
13 protected TextListenerBase(bool local) {
13 protected TextListenerBase(bool global) {
14 Register(this);
14 Register(this);
15 if (local) {
15 if (!global) {
16 m_boundOperation = TraceContext.Current.CurrentOperation;
16 m_boundOperation = TraceContext.Current.CurrentOperation;
17 m_baseIndent = Math.Max(0, m_boundOperation.Level - 1);
17 m_baseIndent = Math.Max(0, m_boundOperation.Level - 1);
18 }
18 }
@@ -36,6 +36,7 namespace Implab.Diagnostics {
36 AssertNotDisposed();
36 AssertNotDisposed();
37
37
38 var formatter = GetService<IEventTextFormatter<TEvent>>();
38 var formatter = GetService<IEventTextFormatter<TEvent>>();
39 var channelName = channel.Name;
39
40
40 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => {
41 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => {
41 TraceContext context = (TraceContext)sender;
42 TraceContext context = (TraceContext)sender;
@@ -43,7 +44,7 namespace Implab.Diagnostics {
43 text.indent -= m_baseIndent;
44 text.indent -= m_baseIndent;
44
45
45 if (IsRelated(context.CurrentOperation))
46 if (IsRelated(context.CurrentOperation))
46 WriteEntry(context, text);
47 WriteEntry(context, text, channelName);
47 };
48 };
48
49
49 if (m_subscriptions.ContainsKey(channel))
50 if (m_subscriptions.ContainsKey(channel))
@@ -98,7 +99,7 namespace Implab.Diagnostics {
98 /// </remarks>
99 /// </remarks>
99 /// <param name="context">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки.</param>
100 /// <param name="context">ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ трассировки.</param>
100 /// <param name="text">ВСкст сообщСния.</param>
101 /// <param name="text">ВСкст сообщСния.</param>
101 protected abstract void WriteEntry(TraceContext context, EventText text);
102 protected abstract void WriteEntry(TraceContext context, EventText text, string channel);
102
103
103 public EventText Format(TraceContext context, object data) {
104 public EventText Format(TraceContext context, object data) {
104 return new EventText {
105 return new EventText {
@@ -25,18 +25,24 namespace Implab.Diagnostics {
25 /// </summary>
25 /// </summary>
26 public static TraceContext Current {
26 public static TraceContext Current {
27 get {
27 get {
28 if (_current == null)
28 if (_current == null) {
29 _current = new TraceContext();
29 _current = new TraceContext();
30 _current.LogEvent(TraceEventType.Created,"[{0}]", _current.ThreadId);
31 }
30 return _current;
32 return _current;
31 }
33 }
32 }
34 }
33
35
34 TraceContext(TraceContext context) {
36 TraceContext(TraceContext context)
37 : this(context, false) {
38 }
39
40 TraceContext(TraceContext context, bool attach) {
35 if (context == null)
41 if (context == null)
36 throw new ArgumentNullException("context");
42 throw new ArgumentNullException("context");
37
43
38 m_currentOperation = context.CurrentOperation;
44 m_currentOperation = context.CurrentOperation;
39 m_bound = context.CurrentOperation;
45 m_bound = attach ? context.BoundOperation : context.CurrentOperation;
40 m_threadId = Thread.CurrentThread.ManagedThreadId;
46 m_threadId = Thread.CurrentThread.ManagedThreadId;
41 }
47 }
42
48
@@ -57,15 +63,15 namespace Implab.Diagnostics {
57 /// контСкстС Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ логичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Ρ‹.
63 /// контСкстС Ρ€Π°Π½Π΅Π΅ Π½Π°Ρ‡Π°Ρ‚Ρ‹Π΅ логичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Ρ‹.
58 /// </para>
64 /// </para>
59 /// <para>
65 /// <para>
60 /// Если ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° состояния ΡΠΎΡΡ‚ΠΎΡΠ»Π°ΡΡŒ, Ρ‚ΠΎ вызываСтся событиС трассировки <see cref="TraceEventType.Transfer"/>.
66 /// Если ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° состояния ΡΠΎΡΡ‚ΠΎΡΠ»Π°ΡΡŒ, Ρ‚ΠΎ вызываСтся событиС трассировки <see cref="TraceEventType.Fork"/>.
61 /// </para>
67 /// </para>
62 /// </remarks>
68 /// </remarks>
63 public static void Transfer(TraceContext from) {
69 public static void Fork(TraceContext from) {
64 if (_current == from)
70 if (_current == from)
65 return;
71 return;
66 if (from != null) {
72 if (from != null) {
67 var context = new TraceContext(from);
73 var context = new TraceContext(from);
68 context.LogEvent(TraceEventType.Transfer, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId);
74 context.LogEvent(TraceEventType.Fork, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId);
69 _current = context;
75 _current = context;
70 } else {
76 } else {
71 _current = new TraceContext();
77 _current = new TraceContext();
@@ -73,7 +79,40 namespace Implab.Diagnostics {
73 }
79 }
74
80
75 /// <summary>
81 /// <summary>
76 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ копию Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста, Π΄Π°Π½Π½ΡƒΡŽ копию ΠΌΠΎΠΆΠ½ΠΎ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ‡Π΅Ρ€Π΅Π· <see cref="Transfer(TraceContext)"/>
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 }
96 }
97
98 /// <summary>
99 /// ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ контСкст трассировки ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠ°, для дальнСйшСй Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ
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)"/>
77 /// </summary>
116 /// </summary>
78 /// <returns>Копия Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста трассировки.</returns>
117 /// <returns>Копия Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ контСкста трассировки.</returns>
79 public static TraceContext Snapshot() {
118 public static TraceContext Snapshot() {
@@ -88,7 +127,7 namespace Implab.Diagnostics {
88 if (action == null)
127 if (action == null)
89 throw new ArgumentNullException("action");
128 throw new ArgumentNullException("action");
90 var old = _current;
129 var old = _current;
91 Transfer(this);
130 Fork(this);
92 try {
131 try {
93 action();
132 action();
94 } finally {
133 } finally {
@@ -11,6 +11,9 namespace Implab.Diagnostics {
11 Error,
11 Error,
12 OperationStarted,
12 OperationStarted,
13 OperationCompleted,
13 OperationCompleted,
14 Transfer
14 Fork,
15 Attach,
16 Detach,
17 Created
15 }
18 }
16 }
19 }
@@ -1,10 +1,14
1 using System;
1 using Implab.Diagnostics;
2 using System;
2 using System.Collections.Generic;
3 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Diagnostics;
4 using System.Linq;
5 using System.Linq;
5 using System.Web;
6 using System.Web;
6
7
7 namespace Implab {
8 namespace Implab {
9 /// <summary>
10 /// ΠžΠ±ΡŠΠ΅ΠΊΡ‚, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ освобоТдСниС рСсурсов.
11 /// </summary>
8 public class Disposable : IDisposable {
12 public class Disposable : IDisposable {
9
13
10 bool m_disposed;
14 bool m_disposed;
@@ -19,7 +23,16 namespace Implab {
19 if (m_disposed)
23 if (m_disposed)
20 throw new ObjectDisposedException(this.ToString());
24 throw new ObjectDisposedException(this.ToString());
21 }
25 }
22
26 /// <summary>
27 /// ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² состояниС <c>Disposed</c> ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ событиС <see cref="Disposed"/>
28 /// </summary>
29 /// <param name="disposing">ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ рСсурсы, ΠΈΠ½Π°Ρ‡Π΅ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄
30 /// Π²Ρ‹Π·Π²Π°Π½ сборщиком мусора ΠΈ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ‚ΡŒ Π’ΠžΠ›Π¬ΠšΠž нСуправляСмыС рСсурсы Π’ΠžΠ›Π¬ΠšΠž этого
31 /// ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.</param>
32 /// <remarks>
33 /// Π”Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ осущСствляСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΡƒΠΆΠ΅ Π±Ρ‹Π» освобоТдСн, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ
34 /// событиС <see cref="Disposed"/>. НС ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ.
35 /// </remarks>
23 protected virtual void Dispose(bool disposing) {
36 protected virtual void Dispose(bool disposing) {
24 if (disposing && !m_disposed) {
37 if (disposing && !m_disposed) {
25 m_disposed = true;
38 m_disposed = true;
@@ -34,8 +47,11 namespace Implab {
34 GC.SuppressFinalize(this);
47 GC.SuppressFinalize(this);
35 }
48 }
36
49
50 /// <summary>
51 /// ЗаписываСт сообщСниС ΠΎΠ± ΡƒΡ‚Π΅Ρ‡ΠΊΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
52 /// </summary>
37 protected virtual void ReportObjectLeaks() {
53 protected virtual void ReportObjectLeaks() {
38 Trace.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
54 TraceLog.TraceWarning("The object is marked as disposable but isn't disposed properly: {0}", this);
39 }
55 }
40
56
41 ~Disposable() {
57 ~Disposable() {
@@ -42,7 +42,7 namespace Implab.Parallels {
42 }
42 }
43
43
44 protected override void Worker() {
44 protected override void Worker() {
45 TraceContext.Transfer(m_traceContext);
45 TraceContext.Fork(m_traceContext);
46 base.Worker();
46 base.Worker();
47 }
47 }
48
48
@@ -99,7 +99,7 namespace Implab.Parallels {
99 }
99 }
100
100
101 protected override void Worker() {
101 protected override void Worker() {
102 TraceContext.Transfer(m_traceContext);
102 TraceContext.Fork(m_traceContext);
103 base.Worker();
103 base.Worker();
104 }
104 }
105
105
@@ -17,7 +17,7 namespace Implab.Parallels {
17 var caller = TraceContext.Snapshot();
17 var caller = TraceContext.Snapshot();
18
18
19 ThreadPool.QueueUserWorkItem(param => {
19 ThreadPool.QueueUserWorkItem(param => {
20 TraceContext.Transfer(caller);
20 TraceContext.Fork(caller);
21 try {
21 try {
22 p.Resolve(func());
22 p.Resolve(func());
23 } catch(Exception e) {
23 } catch(Exception e) {
@@ -34,7 +34,7 namespace Implab.Parallels {
34 var caller = TraceContext.Snapshot();
34 var caller = TraceContext.Snapshot();
35
35
36 var worker = new Thread(() => {
36 var worker = new Thread(() => {
37 TraceContext.Transfer(caller);
37 TraceContext.Fork(caller);
38 try {
38 try {
39 p.Resolve(func());
39 p.Resolve(func());
40 } catch (Exception e) {
40 } catch (Exception e) {
@@ -46,5 +46,26 namespace Implab.Parallels {
46
46
47 return p;
47 return p;
48 }
48 }
49
50
51 public static IPromiseBase InvokeNewThread(Action func) {
52 var p = new Promise<object>();
53
54 var caller = TraceContext.Snapshot();
55
56 var worker = new Thread(() => {
57 TraceContext.Fork(caller);
58 try {
59 func();
60 p.Resolve();
61 } catch (Exception e) {
62 p.Reject(e);
63 }
64 });
65 worker.IsBackground = true;
66 worker.Start();
67
68 return p;
49 }
69 }
50 }
70 }
71 }
General Comments 0
You need to be logged in to leave comments. Login now