using System; using System.Threading; namespace PI.SDK.UI.Threading { internal class UISynchronizationContext : SynchronizationContext, IDisposable { private BlockingQueue _queue; private UIThread _uiThread; internal UIThread CurrentUIThread { get { return _uiThread; } set { _uiThread = value; } } public UISynchronizationContext() : base() { _queue = new BlockingQueue (); _uiThread = new UIThread(_queue); _uiThread.Start(); } public override void Send(SendOrPostCallback d, object state) { // create an item for execution SendOrPostCallbackItem item = new SendOrPostCallbackItem(d, state, ExecutionType.Send); // queue the item _queue.Enqueue(item); // wait for the item execution to end item.ExecutionCompleteWaitHandle.WaitOne(); // if there was an exception, throw it on the caller thread, not the // sta thread. if (item.ExecutedWithException) throw item.Exception; } public override void Post(SendOrPostCallback d, object state) { // queue the item and don't wait for its execution. This is risky because // an unhandled exception will terminate the STA thread. Use with caution. SendOrPostCallbackItem item = new SendOrPostCallbackItem(d, state, ExecutionType.Post); _queue.Enqueue(item); } public void Dispose() { _uiThread.Stop(); } public override SynchronizationContext CreateCopy() { return this; } } }