##// END OF EJS Templates
Fixed InteractiveListener to support OLE and clipboard....
cin -
r215:fe5101083150 v2
parent child
Show More
@@ -1,123 +1,147
1 using Implab.Parallels;
1 using Implab.Parallels;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Linq;
4 using System.Linq;
5 using System.Text;
5 using System.Text;
6 using System.Threading;
6 using System.Threading;
7 using System.Threading.Tasks;
7 using System.Threading.Tasks;
8 using System.Windows.Forms;
8 using System.Windows.Forms;
9
9
10 namespace Implab.Diagnostics.Interactive
10 namespace Implab.Diagnostics.Interactive
11 {
11 {
12 public class InteractiveListener: ListenerBase
12 public class InteractiveListener: ListenerBase
13 {
13 {
14 TraceForm m_form;
14 TraceForm m_form;
15
15
16 SynchronizationContext m_syncGuiThread;
16 SynchronizationContext m_syncGuiThread;
17 readonly Promise m_guiStarted = new Promise();
17 readonly Promise m_guiStarted = new Promise();
18
18
19 readonly IPromise m_guiFinished;
19 readonly IPromise m_guiFinished;
20 // readonly IPromise m_workerFinished = new Promise<object>();
21
20
22 readonly MTQueue<TraceViewItem> m_queue = new MTQueue<TraceViewItem>();
21 readonly MTQueue<TraceViewItem> m_queue = new MTQueue<TraceViewItem>();
23 readonly AutoResetEvent m_queueEvent = new AutoResetEvent(false);
22 readonly AutoResetEvent m_queueEvent = new AutoResetEvent(false);
24
23
25 int m_queueLength;
24 int m_queueLength;
26 bool m_exitPending;
25 bool m_exitPending;
27
26
28 readonly object m_pauseLock = new object();
27 readonly object m_pauseLock = new object();
29 bool m_paused;
28 bool m_paused;
30 readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
29 readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
31
30
32 public InteractiveListener() {
31 public InteractiveListener() {
33 m_guiFinished = AsyncPool.RunThread(GuiThread);
32 m_guiFinished = RunGuiThread();
34 /*m_workerFinished = */AsyncPool.RunThread(QueueThread);
33 AsyncPool.RunThread(QueueThread);
35
34
36 m_guiStarted.Join();
35 m_guiStarted.Join();
37 }
36 }
38
37
39 void GuiThread() {
38 void GuiThread() {
40 m_form = new TraceForm(); // will create SynchronizationContext
39 m_form = new TraceForm(); // will create SynchronizationContext
41
40
42 m_form.PauseEvents += (s,a) => Pause();
41 m_form.PauseEvents += (s,a) => Pause();
43 m_form.ResumeEvents += (s, a) => Resume();
42 m_form.ResumeEvents += (s, a) => Resume();
44
43
45 m_syncGuiThread = SynchronizationContext.Current;
44 m_syncGuiThread = SynchronizationContext.Current;
46 m_guiStarted.Resolve();
45 m_guiStarted.Resolve();
47 Application.Run();
46 Application.Run();
48 }
47 }
49
48
50 void QueueThread() {
49 void QueueThread() {
51 while (!m_exitPending) {
50 while (!m_exitPending) {
52 if (m_paused)
51 if (m_paused)
53 m_pauseEvent.WaitOne();
52 m_pauseEvent.WaitOne();
54
53
55 TraceViewItem item;
54 TraceViewItem item;
56 if (m_queue.TryDequeue(out item)) {
55 if (m_queue.TryDequeue(out item)) {
57 Interlocked.Decrement(ref m_queueLength);
56 Interlocked.Decrement(ref m_queueLength);
58
57
59 m_syncGuiThread.Post(x => m_form.AddTraceEvent(item),null);
58 m_syncGuiThread.Post(x => m_form.AddTraceEvent(item),null);
60 } else {
59 } else {
61 m_queueEvent.WaitOne();
60 m_queueEvent.WaitOne();
62 }
61 }
63 }
62 }
64 }
63 }
65
64
65 public IPromise RunGuiThread() {
66 var p = new Promise();
67
68 var caller = TraceContext.Instance.CurrentOperation;
69
70 var worker = new Thread(() => {
71 TraceContext.Instance.EnterLogicalOperation(caller, false);
72 try {
73 Application.OleRequired();
74 GuiThread();
75 p.Resolve();
76 } catch (Exception e) {
77 p.Reject(e);
78 } finally {
79 TraceContext.Instance.Leave();
80 }
81 });
82 worker.SetApartmentState(ApartmentState.STA);
83 worker.IsBackground = true;
84 worker.Name = string.Format("{0} GUI Thread", nameof(InteractiveListener));
85 worker.Start();
86
87 return p;
88 }
89
66 public void Pause() {
90 public void Pause() {
67 // for consistency we need to set this properties atomically
91 // for consistency we need to set this properties atomically
68 lock (m_pauseLock) {
92 lock (m_pauseLock) {
69 m_pauseEvent.Reset();
93 m_pauseEvent.Reset();
70 m_paused = true;
94 m_paused = true;
71 }
95 }
72 }
96 }
73
97
74 public void Resume() {
98 public void Resume() {
75 // for consistency we need to set this properties atomically
99 // for consistency we need to set this properties atomically
76 lock (m_pauseLock) {
100 lock (m_pauseLock) {
77 m_paused = false;
101 m_paused = false;
78 m_pauseEvent.Set();
102 m_pauseEvent.Set();
79 }
103 }
80 }
104 }
81
105
82 void Enqueue(TraceViewItem item) {
106 void Enqueue(TraceViewItem item) {
83 m_queue.Enqueue(item);
107 m_queue.Enqueue(item);
84 if (Interlocked.Increment(ref m_queueLength) == 1)
108 if (Interlocked.Increment(ref m_queueLength) == 1)
85 m_queueEvent.Set();
109 m_queueEvent.Set();
86 }
110 }
87
111
88 public void ShowForm() {
112 public void ShowForm() {
89 m_syncGuiThread.Post(x => m_form.Show(), null);
113 m_syncGuiThread.Post(x => m_form.Show(), null);
90 }
114 }
91
115
92 public void HideForm() {
116 public void HideForm() {
93 m_syncGuiThread.Post(x => m_form.Hide(), null);
117 m_syncGuiThread.Post(x => m_form.Hide(), null);
94 }
118 }
95
119
96 void Terminate() {
120 void Terminate() {
97 m_exitPending = true;
121 m_exitPending = true;
98 Resume();
122 Resume();
99 m_syncGuiThread.Post(x => Application.ExitThread(), null);
123 m_syncGuiThread.Post(x => Application.ExitThread(), null);
100 }
124 }
101
125
102 protected override void Dispose(bool disposing) {
126 protected override void Dispose(bool disposing) {
103 if (disposing) {
127 if (disposing) {
104 Terminate();
128 Terminate();
105 m_guiFinished.Join();
129 m_guiFinished.Join();
106 }
130 }
107 base.Dispose(disposing);
131 base.Dispose(disposing);
108 }
132 }
109
133
110 public override void Write(LogEventArgs args, object entry) {
134 public override void Write(LogEventArgs args, object entry) {
111 var item = new TraceViewItem {
135 var item = new TraceViewItem {
112 Indent = args.Operation.Level,
136 Indent = args.Operation.Level,
113 Message = entry.ToString(),
137 Message = entry.ToString(),
114 Thread = args.ThreadId,
138 Thread = args.ThreadId,
115 Channel = args.Channel.ToString(),
139 Channel = args.Channel.ToString(),
116 Timestamp = Environment.TickCount,
140 Timestamp = Environment.TickCount,
117 TimeDelta = args.OperationTimeOffset
141 TimeDelta = args.OperationTimeOffset
118 };
142 };
119
143
120 Enqueue(item);
144 Enqueue(item);
121 }
145 }
122 }
146 }
123 }
147 }
@@ -1,144 +1,152
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.Text.RegularExpressions;
5 using System.Text.RegularExpressions;
6 using System.Diagnostics;
6 using System.Diagnostics;
7 using System.Collections;
7 using System.Collections;
8
8
9 #if NET_4_5
9 #if NET_4_5
10 using System.Threading.Tasks;
10 using System.Threading.Tasks;
11 #endif
11 #endif
12
12
13 namespace Implab
13 namespace Implab
14 {
14 {
15 public static class Safe
15 public static class Safe
16 {
16 {
17 public static void ArgumentAssert(bool condition, string paramName) {
17 public static void ArgumentAssert(bool condition, string paramName) {
18 if (!condition)
18 if (!condition)
19 throw new ArgumentException("The parameter is invalid", paramName);
19 throw new ArgumentException("The parameter is invalid", paramName);
20 }
20 }
21
21
22 public static void ArgumentMatch(string value, string paramName, Regex rx) {
22 public static void ArgumentMatch(string value, string paramName, Regex rx) {
23 if (rx == null)
23 if (rx == null)
24 throw new ArgumentNullException("rx");
24 throw new ArgumentNullException("rx");
25 if (!rx.IsMatch(value))
25 if (!rx.IsMatch(value))
26 throw new ArgumentException(String.Format("The prameter value must match {0}", rx), paramName);
26 throw new ArgumentException(String.Format("The prameter value must match {0}", rx), paramName);
27 }
27 }
28
28
29 public static void ArgumentNotEmpty(string value, string paramName) {
29 public static void ArgumentNotEmpty(string value, string paramName) {
30 if (String.IsNullOrEmpty(value))
30 if (String.IsNullOrEmpty(value))
31 throw new ArgumentException("The parameter can't be empty", paramName);
31 throw new ArgumentException("The parameter can't be empty", paramName);
32 }
32 }
33
33
34 public static void ArgumentNotEmpty<T>(T[] value, string paramName) {
34 public static void ArgumentNotEmpty<T>(T[] value, string paramName) {
35 if (value == null || value.Length == 0)
35 if (value == null || value.Length == 0)
36 throw new ArgumentException("The array must be not emty", paramName);
36 throw new ArgumentException("The array must be not emty", paramName);
37 }
37 }
38
38
39 public static void ArgumentNotNull(object value, string paramName) {
39 public static void ArgumentNotNull(object value, string paramName) {
40 if (value == null)
40 if (value == null)
41 throw new ArgumentNullException(paramName);
41 throw new ArgumentNullException(paramName);
42 }
42 }
43
43
44 public static void ArgumentInRange(int value, int min, int max, string paramName) {
44 public static void ArgumentInRange(int value, int min, int max, string paramName) {
45 if (value < min || value > max)
45 if (value < min || value > max)
46 throw new ArgumentOutOfRangeException(paramName);
46 throw new ArgumentOutOfRangeException(paramName);
47 }
47 }
48
48
49 public static void ArgumentOfType(object value, Type type, string paramName) {
49 public static void ArgumentOfType(object value, Type type, string paramName) {
50 if (!type.IsInstanceOfType(value))
50 if (!type.IsInstanceOfType(value))
51 throw new ArgumentException(String.Format("The parameter must be of type {0}", type), paramName);
51 throw new ArgumentException(String.Format("The parameter must be of type {0}", type), paramName);
52 }
52 }
53
53
54 public static void Dispose(params IDisposable[] objects) {
54 public static void Dispose(params IDisposable[] objects) {
55 foreach (var d in objects)
55 foreach (var d in objects)
56 if (d != null)
56 if (d != null)
57 d.Dispose();
57 d.Dispose();
58 }
58 }
59
59
60 public static void Dispose(params object[] objects) {
60 public static void Dispose(params object[] objects) {
61 foreach (var obj in objects) {
61 foreach (var obj in objects) {
62 var d = obj as IDisposable;
62 var d = obj as IDisposable;
63 if (d != null)
63 if (d != null)
64 d.Dispose();
64 d.Dispose();
65 }
65 }
66 }
66 }
67
67
68 public static void Dispose(IEnumerable<IDisposable> objects) {
68 public static void DisposeCollection(IEnumerable<IDisposable> objects) {
69 foreach (var d in objects)
69 foreach (var d in objects)
70 if (d != null)
70 Dispose(d);
71 d.Dispose();
71 }
72
73 public static void DisposeCollection(IEnumerable objects) {
74 foreach (var d in objects)
75 Dispose(d);
72 }
76 }
73
77
74 public static void Dispose(object obj) {
78 public static void Dispose(object obj) {
75 var d = obj as IDisposable;
79 if (obj is IDisposable) {
76 if (d != null)
80 Dispose((IDisposable)obj);
77 d.Dispose();
81 } else if (obj is IEnumerable) {
82 Dispose((IEnumerable)obj);
83 }
78 }
84 }
79
85
86 [DebuggerStepThrough]
80 public static void DispatchEvent<T>(this EventHandler<T> handler, object sender, T args) {
87 public static void DispatchEvent<T>(this EventHandler<T> handler, object sender, T args) {
81 if (handler != null)
88 if (handler != null)
82 handler(sender, args);
89 handler(sender, args);
83 }
90 }
84
91
92 [DebuggerStepThrough]
85 public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) {
93 public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) {
86 if (handler != null)
94 if (handler != null)
87 handler(sender, args);
95 handler(sender, args);
88 }
96 }
89
97
90 [DebuggerStepThrough]
98 [DebuggerStepThrough]
91 public static IPromise<T> Run<T>(Func<T> action) {
99 public static IPromise<T> Run<T>(Func<T> action) {
92 ArgumentNotNull(action, "action");
100 ArgumentNotNull(action, "action");
93
101
94 try {
102 try {
95 return Promise<T>.FromResult(action());
103 return Promise<T>.FromResult(action());
96 } catch (Exception err) {
104 } catch (Exception err) {
97 return Promise<T>.FromException(err);
105 return Promise<T>.FromException(err);
98 }
106 }
99 }
107 }
100
108
101 [DebuggerStepThrough]
109 [DebuggerStepThrough]
102 public static IPromise Run(Action action) {
110 public static IPromise Run(Action action) {
103 ArgumentNotNull(action, "action");
111 ArgumentNotNull(action, "action");
104
112
105 try {
113 try {
106 action();
114 action();
107 return Promise.Success;
115 return Promise.Success;
108 } catch (Exception err) {
116 } catch (Exception err) {
109 return new FailedPromise(err);
117 return new FailedPromise(err);
110 }
118 }
111 }
119 }
112
120
113 [DebuggerStepThrough]
121 [DebuggerStepThrough]
114 public static IPromise Run(Func<IPromise> action) {
122 public static IPromise Run(Func<IPromise> action) {
115 ArgumentNotNull(action, "action");
123 ArgumentNotNull(action, "action");
116
124
117 try {
125 try {
118 return action() ?? new FailedPromise(new Exception("The action returned null"));
126 return action() ?? new FailedPromise(new Exception("The action returned null"));
119 } catch (Exception err) {
127 } catch (Exception err) {
120 return new FailedPromise(err);
128 return new FailedPromise(err);
121 }
129 }
122 }
130 }
123
131
124 public static void NoWait(IPromise promise) {
132 public static void NoWait(IPromise promise) {
125 }
133 }
126
134
127 [DebuggerStepThrough]
135 [DebuggerStepThrough]
128 public static IPromise<T> Run<T>(Func<IPromise<T>> action) {
136 public static IPromise<T> Run<T>(Func<IPromise<T>> action) {
129 ArgumentNotNull(action, "action");
137 ArgumentNotNull(action, "action");
130
138
131 try {
139 try {
132 return action() ?? Promise<T>.FromException(new Exception("The action returned null"));
140 return action() ?? Promise<T>.FromException(new Exception("The action returned null"));
133 } catch (Exception err) {
141 } catch (Exception err) {
134 return Promise<T>.FromException(err);
142 return Promise<T>.FromException(err);
135 }
143 }
136 }
144 }
137
145
138 #if NET_4_5
146 #if NET_4_5
139 public static void NoWait(Task t) {
147 public static void NoWait(Task t) {
140 }
148 }
141 #endif
149 #endif
142
150
143 }
151 }
144 }
152 }
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now