comparison Implab.Diagnostics.Interactive/InteractiveListener.cs @ 47:b181f7bcb259 interactive logger

refactoring, interactive tarce log almost complete
author cin
date Thu, 17 Apr 2014 18:49:36 +0400
parents
children d9d794b61bb9
comparison
equal deleted inserted replaced
46:9ce97b262a7a 47:b181f7bcb259
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 }