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