diff --git a/Implab.Diagnostics.Interactive/InteractiveListener.cs b/Implab.Diagnostics.Interactive/InteractiveListener.cs --- a/Implab.Diagnostics.Interactive/InteractiveListener.cs +++ b/Implab.Diagnostics.Interactive/InteractiveListener.cs @@ -17,7 +17,6 @@ namespace Implab.Diagnostics.Interactive readonly Promise m_guiStarted = new Promise(); readonly IPromise m_guiFinished; - // readonly IPromise m_workerFinished = new Promise(); readonly MTQueue m_queue = new MTQueue(); readonly AutoResetEvent m_queueEvent = new AutoResetEvent(false); @@ -30,8 +29,8 @@ namespace Implab.Diagnostics.Interactive readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true); public InteractiveListener() { - m_guiFinished = AsyncPool.RunThread(GuiThread); - /*m_workerFinished = */AsyncPool.RunThread(QueueThread); + m_guiFinished = RunGuiThread(); + AsyncPool.RunThread(QueueThread); m_guiStarted.Join(); } @@ -63,6 +62,31 @@ namespace Implab.Diagnostics.Interactive } } + public IPromise RunGuiThread() { + var p = new Promise(); + + var caller = TraceContext.Instance.CurrentOperation; + + var worker = new Thread(() => { + TraceContext.Instance.EnterLogicalOperation(caller, false); + try { + Application.OleRequired(); + GuiThread(); + p.Resolve(); + } catch (Exception e) { + p.Reject(e); + } finally { + TraceContext.Instance.Leave(); + } + }); + worker.SetApartmentState(ApartmentState.STA); + worker.IsBackground = true; + worker.Name = string.Format("{0} GUI Thread", nameof(InteractiveListener)); + worker.Start(); + + return p; + } + public void Pause() { // for consistency we need to set this properties atomically lock (m_pauseLock) { diff --git a/Implab/Safe.cs b/Implab/Safe.cs --- a/Implab/Safe.cs +++ b/Implab/Safe.cs @@ -65,23 +65,31 @@ namespace Implab } } - public static void Dispose(IEnumerable objects) { + public static void DisposeCollection(IEnumerable objects) { foreach (var d in objects) - if (d != null) - d.Dispose(); + Dispose(d); + } + + public static void DisposeCollection(IEnumerable objects) { + foreach (var d in objects) + Dispose(d); } public static void Dispose(object obj) { - var d = obj as IDisposable; - if (d != null) - d.Dispose(); + if (obj is IDisposable) { + Dispose((IDisposable)obj); + } else if (obj is IEnumerable) { + Dispose((IEnumerable)obj); + } } + [DebuggerStepThrough] public static void DispatchEvent(this EventHandler handler, object sender, T args) { if (handler != null) handler(sender, args); } + [DebuggerStepThrough] public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) { if (handler != null) handler(sender, args);