##// END OF EJS Templates
refactoring, interactive tarce log almost complete
cin -
r47:b181f7bcb259 interactive logger
parent child
Show More
@@ -0,0 +1,107
1 using Implab.Parallels;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading;
7 using System.Threading.Tasks;
8 using System.Windows.Forms;
9
10 namespace Implab.Diagnostics.Interactive
11 {
12 public class InteractiveListener: Disposable
13 {
14 TraceForm m_form;
15
16 SynchronizationContext m_syncGuiThread;
17
18 readonly IPromiseBase m_guiFinished;
19 readonly Promise<object> m_guiStarted = new Promise<object>();
20
21 readonly IPromiseBase m_workerFinished = new Promise<object>();
22
23 readonly MTQueue<TraceViewItem> m_queue = new MTQueue<TraceViewItem>();
24 readonly AutoResetEvent m_queueEvent = new AutoResetEvent(false);
25
26 int m_queueLength;
27 bool m_exitPending;
28
29 readonly object m_pauseLock = new object();
30 bool m_paused;
31 readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
32
33 public InteractiveListener() {
34 m_guiFinished = AsyncPool.InvokeNewThread(() => {
35 GuiThread();
36 return 0;
37 });
38
39 m_guiStarted.Join();
40 }
41
42 void GuiThread() {
43 m_form = new TraceForm(); // will create SynchronizationContext
44 m_syncGuiThread = SynchronizationContext.Current;
45 m_guiStarted.Resolve();
46 Application.Run();
47 }
48
49 void QueueThread() {
50 while (!m_exitPending) {
51 if (m_paused)
52 m_pauseEvent.WaitOne();
53
54 TraceViewItem item;
55 if (m_queue.TryDequeue(out item)) {
56 Interlocked.Decrement(ref m_queueLength);
57
58 m_syncGuiThread.Send(x => m_form.AddTraceEvent(item),null);
59 } else {
60 m_queueEvent.WaitOne();
61 }
62 }
63 }
64
65 public void Pause() {
66 // for consistency we need to set this properties atomically
67 lock (m_pauseLock) {
68 m_pauseEvent.Reset();
69 m_paused = true;
70 }
71 }
72
73 public void Resume() {
74 // for consistency we need to set this properties atomically
75 lock (m_pauseLock) {
76 m_paused = false;
77 m_pauseEvent.Set();
78 }
79 }
80
81 void Enqueue(TraceViewItem item) {
82 m_queue.Enqueue(item);
83 if (Interlocked.Increment(ref m_queueLength) == 1)
84 m_queueEvent.Set();
85 }
86
87 public void ShowForm() {
88 m_syncGuiThread.Post(x => m_form.Show(), null);
89 }
90
91 public void HideForm() {
92 m_syncGuiThread.Post(x => m_form.Hide(), null);
93 }
94
95 void Terminate() {
96 m_syncGuiThread.Post(x => Application.ExitThread(), null);
97 }
98
99 protected override void Dispose(bool disposing) {
100 if (disposing) {
101 Terminate();
102 m_guiFinished.Join();
103 }
104 base.Dispose(disposing);
105 }
106 }
107 }
@@ -0,0 +1,10
1 <?xml version="1.0" encoding="utf-8"?>
2 <!--
3 This file is automatically generated by Visual Studio .Net. It is
4 used to store generic object data source configuration information.
5 Renaming the file extension or editing the content of this file may
6 cause the file to be unrecognizable by the program.
7 -->
8 <GenericObjectDataSource DisplayName="TraceViewItem" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
9 <TypeInfo>Implab.Diagnostics.Interactive.TraceViewItem, Implab.Diagnostics.Interactive</TypeInfo>
10 </GenericObjectDataSource> No newline at end of file
@@ -41,7 +41,7
41 41 <Reference Include="System.Xml" />
42 42 </ItemGroup>
43 43 <ItemGroup>
44 <Compile Include="InteractiveTracer.cs" />
44 <Compile Include="InteractiveListener.cs" />
45 45 <Compile Include="Properties\AssemblyInfo.cs" />
46 46 <Compile Include="TextStyle.cs" />
47 47 <Compile Include="TraceForm.cs">
@@ -50,16 +50,10
50 50 <Compile Include="TraceForm.Designer.cs">
51 51 <DependentUpon>TraceForm.cs</DependentUpon>
52 52 </Compile>
53 <Compile Include="TraceViewControl.cs">
54 <SubType>UserControl</SubType>
55 </Compile>
56 <Compile Include="TraceViewControl.Designer.cs">
57 <DependentUpon>TraceViewControl.cs</DependentUpon>
58 </Compile>
59 53 <Compile Include="TraceViewItem.cs" />
60 54 </ItemGroup>
61 55 <ItemGroup>
62 <ProjectReference Include="..\external\Implab\Implab.csproj">
56 <ProjectReference Include="..\Implab\Implab.csproj">
63 57 <Project>{f550f1f8-8746-4ad0-9614-855f4c4b7f05}</Project>
64 58 <Name>Implab</Name>
65 59 </ProjectReference>
@@ -68,9 +62,9
68 62 <EmbeddedResource Include="TraceForm.resx">
69 63 <DependentUpon>TraceForm.cs</DependentUpon>
70 64 </EmbeddedResource>
71 <EmbeddedResource Include="TraceViewControl.resx">
72 <DependentUpon>TraceViewControl.cs</DependentUpon>
73 </EmbeddedResource>
65 </ItemGroup>
66 <ItemGroup>
67 <None Include="Properties\DataSources\TraceViewItem.datasource" />
74 68 </ItemGroup>
75 69 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
76 70 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -23,30 +23,100
23 23 /// the contents of this method with the code editor.
24 24 /// </summary>
25 25 private void InitializeComponent() {
26 this.traceViewControl1 = new Implab.Diagnostics.Interactive.TraceViewControl();
26 this.components = new System.ComponentModel.Container();
27 System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
28 System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
29 System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
30 this.eventsDataGrid = new System.Windows.Forms.DataGridView();
31 this.traceViewItemBindingSource = new System.Windows.Forms.BindingSource(this.components);
32 this.threadDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
33 this.messageDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
34 ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).BeginInit();
35 ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).BeginInit();
27 36 this.SuspendLayout();
28 37 //
29 // traceViewControl1
38 // eventsDataGrid
30 39 //
31 this.traceViewControl1.Location = new System.Drawing.Point(13, 13);
32 this.traceViewControl1.Name = "traceViewControl1";
33 this.traceViewControl1.Size = new System.Drawing.Size(267, 248);
34 this.traceViewControl1.TabIndex = 0;
40 this.eventsDataGrid.AllowUserToAddRows = false;
41 this.eventsDataGrid.AllowUserToDeleteRows = false;
42 this.eventsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
43 | System.Windows.Forms.AnchorStyles.Left)
44 | System.Windows.Forms.AnchorStyles.Right)));
45 this.eventsDataGrid.AutoGenerateColumns = false;
46 this.eventsDataGrid.BackgroundColor = System.Drawing.SystemColors.Window;
47 dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
48 dataGridViewCellStyle1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224)))));
49 dataGridViewCellStyle1.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
50 dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
51 dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
52 dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
53 dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
54 this.eventsDataGrid.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
55 this.eventsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
56 this.eventsDataGrid.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
57 this.threadDataGridViewTextBoxColumn,
58 this.messageDataGridViewTextBoxColumn});
59 this.eventsDataGrid.DataSource = this.traceViewItemBindingSource;
60 dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
61 dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Window;
62 dataGridViewCellStyle3.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
63 dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.ControlText;
64 dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;
65 dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
66 dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
67 this.eventsDataGrid.DefaultCellStyle = dataGridViewCellStyle3;
68 this.eventsDataGrid.Location = new System.Drawing.Point(12, 12);
69 this.eventsDataGrid.Name = "eventsDataGrid";
70 this.eventsDataGrid.ReadOnly = true;
71 this.eventsDataGrid.RowHeadersWidth = 17;
72 this.eventsDataGrid.RowTemplate.Resizable = System.Windows.Forms.DataGridViewTriState.False;
73 this.eventsDataGrid.Size = new System.Drawing.Size(939, 480);
74 this.eventsDataGrid.TabIndex = 1;
75 this.eventsDataGrid.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.eventsDataGrid_CellFormatting);
76 //
77 // traceViewItemBindingSource
78 //
79 this.traceViewItemBindingSource.DataSource = typeof(Implab.Diagnostics.Interactive.TraceViewItem);
80 //
81 // threadDataGridViewTextBoxColumn
82 //
83 this.threadDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
84 this.threadDataGridViewTextBoxColumn.DataPropertyName = "Thread";
85 this.threadDataGridViewTextBoxColumn.HeaderText = "TID";
86 this.threadDataGridViewTextBoxColumn.Name = "threadDataGridViewTextBoxColumn";
87 this.threadDataGridViewTextBoxColumn.ReadOnly = true;
88 this.threadDataGridViewTextBoxColumn.Width = 5;
89 //
90 // messageDataGridViewTextBoxColumn
91 //
92 this.messageDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
93 this.messageDataGridViewTextBoxColumn.DataPropertyName = "FormattedMessage";
94 dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
95 this.messageDataGridViewTextBoxColumn.DefaultCellStyle = dataGridViewCellStyle2;
96 this.messageDataGridViewTextBoxColumn.HeaderText = "Message";
97 this.messageDataGridViewTextBoxColumn.Name = "messageDataGridViewTextBoxColumn";
98 this.messageDataGridViewTextBoxColumn.ReadOnly = true;
35 99 //
36 100 // TraceForm
37 101 //
38 102 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
39 103 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
40 this.ClientSize = new System.Drawing.Size(292, 273);
41 this.Controls.Add(this.traceViewControl1);
104 this.ClientSize = new System.Drawing.Size(963, 504);
105 this.Controls.Add(this.eventsDataGrid);
42 106 this.Name = "TraceForm";
43 107 this.Text = "TraceForm";
108 ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).EndInit();
109 ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).EndInit();
44 110 this.ResumeLayout(false);
45 111
46 112 }
47 113
48 114 #endregion
49 115
50 private TraceViewControl traceViewControl1;
116 private System.Windows.Forms.DataGridView eventsDataGrid;
117 private System.Windows.Forms.BindingSource traceViewItemBindingSource;
118 private System.Windows.Forms.DataGridViewTextBoxColumn threadDataGridViewTextBoxColumn;
119 private System.Windows.Forms.DataGridViewTextBoxColumn messageDataGridViewTextBoxColumn;
120
51 121 }
52 122 } No newline at end of file
@@ -10,8 +10,12 using System.Windows.Forms;
10 10
11 11 namespace Implab.Diagnostics.Interactive {
12 12 public partial class TraceForm : Form {
13 readonly Dictionary<int, Color> m_threadColors = new Dictionary<int,Color>();
14 readonly Random m_rand = new Random();
15
13 16 public TraceForm() {
14 17 InitializeComponent();
18
15 19 }
16 20
17 21 protected override void OnFormClosing(FormClosingEventArgs e) {
@@ -21,5 +25,34 namespace Implab.Diagnostics.Interactive
21 25 Hide();
22 26 }
23 27 }
28
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) {
40 traceViewItemBindingSource.Add(item);
41 }
42
43 Color GetThreadColor(int thread) {
44 Color result;
45 if (!m_threadColors.TryGetValue(thread, out result)) {
46 result = Color.FromArgb(m_rand.Next(4)*64, m_rand.Next(4)*64, m_rand.Next(4)*64);
47 m_threadColors[thread] = result;
48 }
49 return result;
50 }
51
52 private void eventsDataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
53 var data = (TraceViewItem)traceViewItemBindingSource[e.RowIndex];
54 e.CellStyle.Padding = new Padding(data.Indent * 10,0,0,0);
55 e.CellStyle.ForeColor = GetThreadColor(data.Thread);
24 56 }
25 57 }
58 }
@@ -117,4 +117,7
117 117 <resheader name="writer">
118 118 <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119 119 </resheader>
120 <metadata name="traceViewItemBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
121 <value>17, 17</value>
122 </metadata>
120 123 </root> No newline at end of file
@@ -5,10 +5,21 using System.Text;
5 5 using System.Threading.Tasks;
6 6
7 7 namespace Implab.Diagnostics.Interactive {
8 public struct TraceViewItem {
9 public string message;
10 public int timestamp;
11 public int indent;
12 public int thread;
8 public class TraceViewItem {
9 string m_formattedValue;
10
11 public string Message { get; set; }
12 public int Timestamp { get; set; }
13 public int Indent { get; set; }
14 public int Thread { get; set; }
15
16 public string FormattedMessage {
17 get {
18 if (m_formattedValue == null) {
19 m_formattedValue = Message.Replace("\r",String.Empty).Replace("\n", " | ");
20 }
21 return m_formattedValue;
13 22 }
14 23 }
24 }
25 }
@@ -23,6 +23,7 namespace Implab.Diagnostics {
23 23
24 24 lock (m_textWriter) {
25 25 if (!IsDisposed) {
26 // тут гарантировано еще не освобожден m_textWriter
26 27 m_textWriter.WriteLine(msg.ToString());
27 28 m_textWriter.Flush();
28 29 }
@@ -33,6 +34,7 namespace Implab.Diagnostics {
33 34 protected override void Dispose(bool disposing) {
34 35 base.Dispose(disposing);
35 36 if (disposing) {
37 // IsDisposed = true
36 38 lock (m_textWriter) {
37 39 Safe.Dispose(m_textWriter);
38 40 }
@@ -89,6 +89,15 namespace Implab.Diagnostics {
89 89 }
90 90 }
91 91
92 /// <summary>
93 /// Вызывается для записи текста сообщения, в журнал.
94 /// </summary>
95 /// <remarks>
96 /// Данный метод может вызваться из разных потоков одновременно. Возможна ситуация, когда
97 /// данный метод вызывается уже после освобождения ообъекта методом <see cref="Dispose()"/>.
98 /// </remarks>
99 /// <param name="context">Контекст трассировки.</param>
100 /// <param name="text">Текст сообщения.</param>
92 101 protected abstract void WriteEntry(TraceContext context, EventText text);
93 102
94 103 public EventText Format(TraceContext context, object data) {
@@ -110,10 +119,10 namespace Implab.Diagnostics {
110 119 }
111 120
112 121 protected override void Dispose(bool disposing) {
122 base.Dispose(disposing);
113 123 if (disposing) {
114 124 UnsubscribeAll();
115 125 }
116 base.Dispose(disposing);
117 126 }
118 127 }
119 128 }
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now