##// 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
@@ -1,83 +1,77
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
3 <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4 <PropertyGroup>
4 <PropertyGroup>
5 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7 <ProjectGuid>{1DB7DB0C-8AA9-484B-A681-33AE94038391}</ProjectGuid>
7 <ProjectGuid>{1DB7DB0C-8AA9-484B-A681-33AE94038391}</ProjectGuid>
8 <OutputType>Library</OutputType>
8 <OutputType>Library</OutputType>
9 <AppDesignerFolder>Properties</AppDesignerFolder>
9 <AppDesignerFolder>Properties</AppDesignerFolder>
10 <RootNamespace>Implab.Diagnostics.Interactive</RootNamespace>
10 <RootNamespace>Implab.Diagnostics.Interactive</RootNamespace>
11 <AssemblyName>Implab.Diagnostics.Interactive</AssemblyName>
11 <AssemblyName>Implab.Diagnostics.Interactive</AssemblyName>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13 <FileAlignment>512</FileAlignment>
13 <FileAlignment>512</FileAlignment>
14 </PropertyGroup>
14 </PropertyGroup>
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
17 <DebugType>full</DebugType>
17 <DebugType>full</DebugType>
18 <Optimize>false</Optimize>
18 <Optimize>false</Optimize>
19 <OutputPath>bin\Debug\</OutputPath>
19 <OutputPath>bin\Debug\</OutputPath>
20 <DefineConstants>DEBUG;TRACE</DefineConstants>
20 <DefineConstants>DEBUG;TRACE</DefineConstants>
21 <ErrorReport>prompt</ErrorReport>
21 <ErrorReport>prompt</ErrorReport>
22 <WarningLevel>4</WarningLevel>
22 <WarningLevel>4</WarningLevel>
23 </PropertyGroup>
23 </PropertyGroup>
24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
24 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
25 <DebugType>pdbonly</DebugType>
25 <DebugType>pdbonly</DebugType>
26 <Optimize>true</Optimize>
26 <Optimize>true</Optimize>
27 <OutputPath>bin\Release\</OutputPath>
27 <OutputPath>bin\Release\</OutputPath>
28 <DefineConstants>TRACE</DefineConstants>
28 <DefineConstants>TRACE</DefineConstants>
29 <ErrorReport>prompt</ErrorReport>
29 <ErrorReport>prompt</ErrorReport>
30 <WarningLevel>4</WarningLevel>
30 <WarningLevel>4</WarningLevel>
31 </PropertyGroup>
31 </PropertyGroup>
32 <ItemGroup>
32 <ItemGroup>
33 <Reference Include="System" />
33 <Reference Include="System" />
34 <Reference Include="System.Core" />
34 <Reference Include="System.Core" />
35 <Reference Include="System.Drawing" />
35 <Reference Include="System.Drawing" />
36 <Reference Include="System.Windows.Forms" />
36 <Reference Include="System.Windows.Forms" />
37 <Reference Include="System.Xml.Linq" />
37 <Reference Include="System.Xml.Linq" />
38 <Reference Include="System.Data.DataSetExtensions" />
38 <Reference Include="System.Data.DataSetExtensions" />
39 <Reference Include="Microsoft.CSharp" />
39 <Reference Include="Microsoft.CSharp" />
40 <Reference Include="System.Data" />
40 <Reference Include="System.Data" />
41 <Reference Include="System.Xml" />
41 <Reference Include="System.Xml" />
42 </ItemGroup>
42 </ItemGroup>
43 <ItemGroup>
43 <ItemGroup>
44 <Compile Include="InteractiveTracer.cs" />
44 <Compile Include="InteractiveListener.cs" />
45 <Compile Include="Properties\AssemblyInfo.cs" />
45 <Compile Include="Properties\AssemblyInfo.cs" />
46 <Compile Include="TextStyle.cs" />
46 <Compile Include="TextStyle.cs" />
47 <Compile Include="TraceForm.cs">
47 <Compile Include="TraceForm.cs">
48 <SubType>Form</SubType>
48 <SubType>Form</SubType>
49 </Compile>
49 </Compile>
50 <Compile Include="TraceForm.Designer.cs">
50 <Compile Include="TraceForm.Designer.cs">
51 <DependentUpon>TraceForm.cs</DependentUpon>
51 <DependentUpon>TraceForm.cs</DependentUpon>
52 </Compile>
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 <Compile Include="TraceViewItem.cs" />
53 <Compile Include="TraceViewItem.cs" />
60 </ItemGroup>
54 </ItemGroup>
61 <ItemGroup>
55 <ItemGroup>
62 <ProjectReference Include="..\external\Implab\Implab.csproj">
56 <ProjectReference Include="..\Implab\Implab.csproj">
63 <Project>{f550f1f8-8746-4ad0-9614-855f4c4b7f05}</Project>
57 <Project>{f550f1f8-8746-4ad0-9614-855f4c4b7f05}</Project>
64 <Name>Implab</Name>
58 <Name>Implab</Name>
65 </ProjectReference>
59 </ProjectReference>
66 </ItemGroup>
60 </ItemGroup>
67 <ItemGroup>
61 <ItemGroup>
68 <EmbeddedResource Include="TraceForm.resx">
62 <EmbeddedResource Include="TraceForm.resx">
69 <DependentUpon>TraceForm.cs</DependentUpon>
63 <DependentUpon>TraceForm.cs</DependentUpon>
70 </EmbeddedResource>
64 </EmbeddedResource>
71 <EmbeddedResource Include="TraceViewControl.resx">
65 </ItemGroup>
72 <DependentUpon>TraceViewControl.cs</DependentUpon>
66 <ItemGroup>
73 </EmbeddedResource>
67 <None Include="Properties\DataSources\TraceViewItem.datasource" />
74 </ItemGroup>
68 </ItemGroup>
75 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
69 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
76 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
70 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
77 Other similar extension points exist, see Microsoft.Common.targets.
71 Other similar extension points exist, see Microsoft.Common.targets.
78 <Target Name="BeforeBuild">
72 <Target Name="BeforeBuild">
79 </Target>
73 </Target>
80 <Target Name="AfterBuild">
74 <Target Name="AfterBuild">
81 </Target>
75 </Target>
82 -->
76 -->
83 </Project> No newline at end of file
77 </Project>
@@ -1,52 +1,122
1 namespace Implab.Diagnostics.Interactive {
1 namespace Implab.Diagnostics.Interactive {
2 partial class TraceForm {
2 partial class TraceForm {
3 /// <summary>
3 /// <summary>
4 /// Required designer variable.
4 /// Required designer variable.
5 /// </summary>
5 /// </summary>
6 private System.ComponentModel.IContainer components = null;
6 private System.ComponentModel.IContainer components = null;
7
7
8 /// <summary>
8 /// <summary>
9 /// Clean up any resources being used.
9 /// Clean up any resources being used.
10 /// </summary>
10 /// </summary>
11 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
11 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
12 protected override void Dispose(bool disposing) {
12 protected override void Dispose(bool disposing) {
13 if (disposing && (components != null)) {
13 if (disposing && (components != null)) {
14 components.Dispose();
14 components.Dispose();
15 }
15 }
16 base.Dispose(disposing);
16 base.Dispose(disposing);
17 }
17 }
18
18
19 #region Windows Form Designer generated code
19 #region Windows Form Designer generated code
20
20
21 /// <summary>
21 /// <summary>
22 /// Required method for Designer support - do not modify
22 /// Required method for Designer support - do not modify
23 /// the contents of this method with the code editor.
23 /// the contents of this method with the code editor.
24 /// </summary>
24 /// </summary>
25 private void InitializeComponent() {
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 this.SuspendLayout();
36 this.SuspendLayout();
28 //
37 //
29 // traceViewControl1
38 // eventsDataGrid
30 //
39 //
31 this.traceViewControl1.Location = new System.Drawing.Point(13, 13);
40 this.eventsDataGrid.AllowUserToAddRows = false;
32 this.traceViewControl1.Name = "traceViewControl1";
41 this.eventsDataGrid.AllowUserToDeleteRows = false;
33 this.traceViewControl1.Size = new System.Drawing.Size(267, 248);
42 this.eventsDataGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
34 this.traceViewControl1.TabIndex = 0;
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 // TraceForm
100 // TraceForm
37 //
101 //
38 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
102 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
39 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
103 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
40 this.ClientSize = new System.Drawing.Size(292, 273);
104 this.ClientSize = new System.Drawing.Size(963, 504);
41 this.Controls.Add(this.traceViewControl1);
105 this.Controls.Add(this.eventsDataGrid);
42 this.Name = "TraceForm";
106 this.Name = "TraceForm";
43 this.Text = "TraceForm";
107 this.Text = "TraceForm";
108 ((System.ComponentModel.ISupportInitialize)(this.eventsDataGrid)).EndInit();
109 ((System.ComponentModel.ISupportInitialize)(this.traceViewItemBindingSource)).EndInit();
44 this.ResumeLayout(false);
110 this.ResumeLayout(false);
45
111
46 }
112 }
47
113
48 #endregion
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 } No newline at end of file
122 }
@@ -1,25 +1,58
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.ComponentModel;
3 using System.ComponentModel;
4 using System.Data;
4 using System.Data;
5 using System.Drawing;
5 using System.Drawing;
6 using System.Linq;
6 using System.Linq;
7 using System.Text;
7 using System.Text;
8 using System.Threading.Tasks;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
9 using System.Windows.Forms;
10
10
11 namespace Implab.Diagnostics.Interactive {
11 namespace Implab.Diagnostics.Interactive {
12 public partial class TraceForm : Form {
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 public TraceForm() {
16 public TraceForm() {
14 InitializeComponent();
17 InitializeComponent();
18
15 }
19 }
16
20
17 protected override void OnFormClosing(FormClosingEventArgs e) {
21 protected override void OnFormClosing(FormClosingEventArgs e) {
18 base.OnFormClosing(e);
22 base.OnFormClosing(e);
19 if (!e.Cancel && e.CloseReason == CloseReason.UserClosing) {
23 if (!e.Cancel && e.CloseReason == CloseReason.UserClosing) {
20 e.Cancel = true;
24 e.Cancel = true;
21 Hide();
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);
56 }
24 }
57 }
25 }
58 }
@@ -1,120 +1,123
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <root>
2 <root>
3 <!--
3 <!--
4 Microsoft ResX Schema
4 Microsoft ResX Schema
5
5
6 Version 2.0
6 Version 2.0
7
7
8 The primary goals of this format is to allow a simple XML format
8 The primary goals of this format is to allow a simple XML format
9 that is mostly human readable. The generation and parsing of the
9 that is mostly human readable. The generation and parsing of the
10 various data types are done through the TypeConverter classes
10 various data types are done through the TypeConverter classes
11 associated with the data types.
11 associated with the data types.
12
12
13 Example:
13 Example:
14
14
15 ... ado.net/XML headers & schema ...
15 ... ado.net/XML headers & schema ...
16 <resheader name="resmimetype">text/microsoft-resx</resheader>
16 <resheader name="resmimetype">text/microsoft-resx</resheader>
17 <resheader name="version">2.0</resheader>
17 <resheader name="version">2.0</resheader>
18 <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
18 <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19 <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
19 <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
20 <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
20 <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
21 <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
21 <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
22 <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
22 <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
23 <value>[base64 mime encoded serialized .NET Framework object]</value>
23 <value>[base64 mime encoded serialized .NET Framework object]</value>
24 </data>
24 </data>
25 <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
25 <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
26 <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
26 <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
27 <comment>This is a comment</comment>
27 <comment>This is a comment</comment>
28 </data>
28 </data>
29
29
30 There are any number of "resheader" rows that contain simple
30 There are any number of "resheader" rows that contain simple
31 name/value pairs.
31 name/value pairs.
32
32
33 Each data row contains a name, and value. The row also contains a
33 Each data row contains a name, and value. The row also contains a
34 type or mimetype. Type corresponds to a .NET class that support
34 type or mimetype. Type corresponds to a .NET class that support
35 text/value conversion through the TypeConverter architecture.
35 text/value conversion through the TypeConverter architecture.
36 Classes that don't support this are serialized and stored with the
36 Classes that don't support this are serialized and stored with the
37 mimetype set.
37 mimetype set.
38
38
39 The mimetype is used for serialized objects, and tells the
39 The mimetype is used for serialized objects, and tells the
40 ResXResourceReader how to depersist the object. This is currently not
40 ResXResourceReader how to depersist the object. This is currently not
41 extensible. For a given mimetype the value must be set accordingly:
41 extensible. For a given mimetype the value must be set accordingly:
42
42
43 Note - application/x-microsoft.net.object.binary.base64 is the format
43 Note - application/x-microsoft.net.object.binary.base64 is the format
44 that the ResXResourceWriter will generate, however the reader can
44 that the ResXResourceWriter will generate, however the reader can
45 read any of the formats listed below.
45 read any of the formats listed below.
46
46
47 mimetype: application/x-microsoft.net.object.binary.base64
47 mimetype: application/x-microsoft.net.object.binary.base64
48 value : The object must be serialized with
48 value : The object must be serialized with
49 : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
49 : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
50 : and then encoded with base64 encoding.
50 : and then encoded with base64 encoding.
51
51
52 mimetype: application/x-microsoft.net.object.soap.base64
52 mimetype: application/x-microsoft.net.object.soap.base64
53 value : The object must be serialized with
53 value : The object must be serialized with
54 : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
54 : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
55 : and then encoded with base64 encoding.
55 : and then encoded with base64 encoding.
56
56
57 mimetype: application/x-microsoft.net.object.bytearray.base64
57 mimetype: application/x-microsoft.net.object.bytearray.base64
58 value : The object must be serialized into a byte array
58 value : The object must be serialized into a byte array
59 : using a System.ComponentModel.TypeConverter
59 : using a System.ComponentModel.TypeConverter
60 : and then encoded with base64 encoding.
60 : and then encoded with base64 encoding.
61 -->
61 -->
62 <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
62 <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
63 <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
63 <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
64 <xsd:element name="root" msdata:IsDataSet="true">
64 <xsd:element name="root" msdata:IsDataSet="true">
65 <xsd:complexType>
65 <xsd:complexType>
66 <xsd:choice maxOccurs="unbounded">
66 <xsd:choice maxOccurs="unbounded">
67 <xsd:element name="metadata">
67 <xsd:element name="metadata">
68 <xsd:complexType>
68 <xsd:complexType>
69 <xsd:sequence>
69 <xsd:sequence>
70 <xsd:element name="value" type="xsd:string" minOccurs="0" />
70 <xsd:element name="value" type="xsd:string" minOccurs="0" />
71 </xsd:sequence>
71 </xsd:sequence>
72 <xsd:attribute name="name" use="required" type="xsd:string" />
72 <xsd:attribute name="name" use="required" type="xsd:string" />
73 <xsd:attribute name="type" type="xsd:string" />
73 <xsd:attribute name="type" type="xsd:string" />
74 <xsd:attribute name="mimetype" type="xsd:string" />
74 <xsd:attribute name="mimetype" type="xsd:string" />
75 <xsd:attribute ref="xml:space" />
75 <xsd:attribute ref="xml:space" />
76 </xsd:complexType>
76 </xsd:complexType>
77 </xsd:element>
77 </xsd:element>
78 <xsd:element name="assembly">
78 <xsd:element name="assembly">
79 <xsd:complexType>
79 <xsd:complexType>
80 <xsd:attribute name="alias" type="xsd:string" />
80 <xsd:attribute name="alias" type="xsd:string" />
81 <xsd:attribute name="name" type="xsd:string" />
81 <xsd:attribute name="name" type="xsd:string" />
82 </xsd:complexType>
82 </xsd:complexType>
83 </xsd:element>
83 </xsd:element>
84 <xsd:element name="data">
84 <xsd:element name="data">
85 <xsd:complexType>
85 <xsd:complexType>
86 <xsd:sequence>
86 <xsd:sequence>
87 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
87 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
88 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
88 <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
89 </xsd:sequence>
89 </xsd:sequence>
90 <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
90 <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
91 <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
91 <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
92 <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
92 <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
93 <xsd:attribute ref="xml:space" />
93 <xsd:attribute ref="xml:space" />
94 </xsd:complexType>
94 </xsd:complexType>
95 </xsd:element>
95 </xsd:element>
96 <xsd:element name="resheader">
96 <xsd:element name="resheader">
97 <xsd:complexType>
97 <xsd:complexType>
98 <xsd:sequence>
98 <xsd:sequence>
99 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
99 <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
100 </xsd:sequence>
100 </xsd:sequence>
101 <xsd:attribute name="name" type="xsd:string" use="required" />
101 <xsd:attribute name="name" type="xsd:string" use="required" />
102 </xsd:complexType>
102 </xsd:complexType>
103 </xsd:element>
103 </xsd:element>
104 </xsd:choice>
104 </xsd:choice>
105 </xsd:complexType>
105 </xsd:complexType>
106 </xsd:element>
106 </xsd:element>
107 </xsd:schema>
107 </xsd:schema>
108 <resheader name="resmimetype">
108 <resheader name="resmimetype">
109 <value>text/microsoft-resx</value>
109 <value>text/microsoft-resx</value>
110 </resheader>
110 </resheader>
111 <resheader name="version">
111 <resheader name="version">
112 <value>2.0</value>
112 <value>2.0</value>
113 </resheader>
113 </resheader>
114 <resheader name="reader">
114 <resheader name="reader">
115 <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
115 <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
116 </resheader>
116 </resheader>
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="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 </root> No newline at end of file
123 </root>
@@ -1,14 +1,25
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5 using System.Threading.Tasks;
5 using System.Threading.Tasks;
6
6
7 namespace Implab.Diagnostics.Interactive {
7 namespace Implab.Diagnostics.Interactive {
8 public struct TraceViewItem {
8 public class TraceViewItem {
9 public string message;
9 string m_formattedValue;
10 public int timestamp;
10
11 public int indent;
11 public string Message { get; set; }
12 public int thread;
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;
22 }
23 }
13 }
24 }
14 }
25 }
@@ -1,44 +1,46
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.IO;
3 using System.IO;
4 using System.Linq;
4 using System.Linq;
5 using System.Text;
5 using System.Text;
6
6
7 namespace Implab.Diagnostics {
7 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 local) : base(local) {
12 m_textWriter = File.CreateText(fileName);
12 m_textWriter = File.CreateText(fileName);
13
13
14 m_textWriter.WriteLine("LOG {0}", DateTime.Now);
14 m_textWriter.WriteLine("LOG {0}", DateTime.Now);
15 Register(this);
15 Register(this);
16 }
16 }
17
17
18 protected override void WriteEntry(TraceContext context, EventText text) {
18 protected override void WriteEntry(TraceContext context, EventText text) {
19 var msg = new StringBuilder();
19 var msg = new StringBuilder();
20 for (int i = 0; i < text.indent; i++)
20 for (int i = 0; i < text.indent; i++)
21 msg.Append(" ");
21 msg.Append(" ");
22 msg.AppendFormat("[{0}]: {1}", context.ThreadId, text.content);
22 msg.AppendFormat("[{0}]: {1}", context.ThreadId, text.content);
23
23
24 lock (m_textWriter) {
24 lock (m_textWriter) {
25 if (!IsDisposed) {
25 if (!IsDisposed) {
26 // тут гарантировано еще не освобожден m_textWriter
26 m_textWriter.WriteLine(msg.ToString());
27 m_textWriter.WriteLine(msg.ToString());
27 m_textWriter.Flush();
28 m_textWriter.Flush();
28 }
29 }
29 }
30 }
30 }
31 }
31
32
32
33
33 protected override void Dispose(bool disposing) {
34 protected override void Dispose(bool disposing) {
34 base.Dispose(disposing);
35 base.Dispose(disposing);
35 if (disposing) {
36 if (disposing) {
37 // IsDisposed = true
36 lock (m_textWriter) {
38 lock (m_textWriter) {
37 Safe.Dispose(m_textWriter);
39 Safe.Dispose(m_textWriter);
38 }
40 }
39 }
41 }
40 }
42 }
41
43
42
44
43 }
45 }
44 }
46 }
@@ -1,119 +1,128
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5
5
6 namespace Implab.Diagnostics {
6 namespace Implab.Diagnostics {
7 public abstract class TextListenerBase : ServiceLocator, IEventTextFormatter<object>, IEventTextFormatter<TraceEvent> {
7 public abstract class TextListenerBase : ServiceLocator, IEventTextFormatter<object>, IEventTextFormatter<TraceEvent> {
8
8
9 readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>();
9 readonly Dictionary<object, Action> m_subscriptions = new Dictionary<object, Action>();
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 local) {
14 Register(this);
14 Register(this);
15 if (local) {
15 if (local) {
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 }
19 }
19 }
20
20
21 public void Subscribe(Type eventType) {
21 public void Subscribe(Type eventType) {
22 if (eventType == null)
22 if (eventType == null)
23 throw new ArgumentNullException("eventType");
23 throw new ArgumentNullException("eventType");
24 GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null);
24 GetType().GetMethod("Subscribe", new Type[0]).MakeGenericMethod(eventType).Invoke(this, null);
25 }
25 }
26
26
27 public void Subscribe<TEvent>() {
27 public void Subscribe<TEvent>() {
28 Subscribe<TEvent>(LogChannel<TEvent>.Default);
28 Subscribe<TEvent>(LogChannel<TEvent>.Default);
29 }
29 }
30
30
31 public void Subscribe<TEvent>(LogChannel<TEvent> channel) {
31 public void Subscribe<TEvent>(LogChannel<TEvent> channel) {
32 if (channel == null)
32 if (channel == null)
33 throw new ArgumentNullException("channel");
33 throw new ArgumentNullException("channel");
34
34
35 lock (m_subscriptions) {
35 lock (m_subscriptions) {
36 AssertNotDisposed();
36 AssertNotDisposed();
37
37
38 var formatter = GetService<IEventTextFormatter<TEvent>>();
38 var formatter = GetService<IEventTextFormatter<TEvent>>();
39
39
40 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => {
40 EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => {
41 TraceContext context = (TraceContext)sender;
41 TraceContext context = (TraceContext)sender;
42 var text = formatter.Format(context, args.Value);
42 var text = formatter.Format(context, args.Value);
43 text.indent -= m_baseIndent;
43 text.indent -= m_baseIndent;
44
44
45 if (IsRelated(context.CurrentOperation))
45 if (IsRelated(context.CurrentOperation))
46 WriteEntry(context, text);
46 WriteEntry(context, text);
47 };
47 };
48
48
49 if (m_subscriptions.ContainsKey(channel))
49 if (m_subscriptions.ContainsKey(channel))
50 return;
50 return;
51
51
52 channel.Events += handler;
52 channel.Events += handler;
53
53
54 Action unsubscribe = () => {
54 Action unsubscribe = () => {
55 channel.Events -= handler;
55 channel.Events -= handler;
56 };
56 };
57
57
58 m_subscriptions.Add(channel, unsubscribe);
58 m_subscriptions.Add(channel, unsubscribe);
59 }
59 }
60 }
60 }
61
61
62 public bool IsRelated(LogicalOperation op) {
62 public bool IsRelated(LogicalOperation op) {
63 if (m_boundOperation == null)
63 if (m_boundOperation == null)
64 return true;
64 return true;
65
65
66 while (op != m_boundOperation && op.Level > m_boundOperation.Level)
66 while (op != m_boundOperation && op.Level > m_boundOperation.Level)
67 op = op.Parent;
67 op = op.Parent;
68 return op == m_boundOperation;
68 return op == m_boundOperation;
69 }
69 }
70
70
71 public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) {
71 public void Unsubscribe<TEvent>(LogChannel<TEvent> channel) {
72 if (channel == null)
72 if (channel == null)
73 throw new ArgumentNullException("channel");
73 throw new ArgumentNullException("channel");
74
74
75 lock (m_subscriptions) {
75 lock (m_subscriptions) {
76 Action subscription;
76 Action subscription;
77 if (m_subscriptions.TryGetValue(channel, out subscription)) {
77 if (m_subscriptions.TryGetValue(channel, out subscription)) {
78 subscription();
78 subscription();
79 m_subscriptions.Remove(channel);
79 m_subscriptions.Remove(channel);
80 }
80 }
81 }
81 }
82 }
82 }
83
83
84 public void UnsubscribeAll() {
84 public void UnsubscribeAll() {
85 lock (m_subscriptions) {
85 lock (m_subscriptions) {
86 foreach (var subscription in m_subscriptions.Values)
86 foreach (var subscription in m_subscriptions.Values)
87 subscription();
87 subscription();
88 m_subscriptions.Clear();
88 m_subscriptions.Clear();
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 protected abstract void WriteEntry(TraceContext context, EventText text);
101 protected abstract void WriteEntry(TraceContext context, EventText text);
93
102
94 public EventText Format(TraceContext context, object data) {
103 public EventText Format(TraceContext context, object data) {
95 return new EventText {
104 return new EventText {
96 indent = context.CurrentOperation.Level,
105 indent = context.CurrentOperation.Level,
97 content = data.ToString()
106 content = data.ToString()
98 };
107 };
99 }
108 }
100
109
101 public EventText Format(TraceContext context, TraceEvent data) {
110 public EventText Format(TraceContext context, TraceEvent data) {
102 var level = context.CurrentOperation.Level;
111 var level = context.CurrentOperation.Level;
103 if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted)
112 if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted)
104 level--;
113 level--;
105
114
106 return new EventText {
115 return new EventText {
107 indent = level,
116 indent = level,
108 content = data.ToString()
117 content = data.ToString()
109 };
118 };
110 }
119 }
111
120
112 protected override void Dispose(bool disposing) {
121 protected override void Dispose(bool disposing) {
122 base.Dispose(disposing);
113 if (disposing) {
123 if (disposing) {
114 UnsubscribeAll();
124 UnsubscribeAll();
115 }
125 }
116 base.Dispose(disposing);
117 }
126 }
118 }
127 }
119 }
128 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now