using System; using System.Collections.Generic; using System.Windows.Forms; using System.Linq; using System.Text; namespace TradeIdeas.TIQ.GUI { /// /// I need to find a better place for this! /// public static class MiscHelper { /// /// This will try to execute a block of code in the GUI thread. If the control has /// been distroyed, the code will not execute. It is safe to call this from the GUI /// thread, in which case we will just call the code immediately. It is a good idea /// to call this function (or at least InvokeRequired) even if you know that you are /// in the wrong thread. Calling Control.Invoke will fail if the control has been /// destroyed. Calling IsDisposed without calling InvokeRequired can lead to a race /// condition. /// /// We use this to access the GUI thread. /// We try to execute this code. public static void InvokeIfRequired(this Control control, MethodInvoker code) { if (control.InvokeRequired) { try { // Thread.Sleep(5000); // Test for a possible race condition. control.Invoke(code); } catch (InvalidOperationException) { // This probably means that the window was disposed of after the call to InvokeRequired // but before the call to Invoke(). // Note: Most of our code does not check for this race condition. It probably should. // This probably doesn't happen very often. } } else if (!control.IsDisposed) code(); } /// /// Similar to but this calls BeginInvoke rather than Invoke. /// It seems like most people probably want this. But not everyone. We got a few strange /// bugs when we tried to move everyone to this. /// /// If you have a choice, you should use this rather than InvokeIfRequired. You don't want /// the TCP/IP read thread to be locked up while doing a slow GUI operation. /// /// /// public static void BeginInvokeIfRequired(this Control control, MethodInvoker code) { if (control.InvokeRequired) { try { // Thread.Sleep(5000); // Test for a possible race condition. control.BeginInvoke(code); } catch (InvalidOperationException) { // This probably means that the window was disposed of after the call to InvokeRequired // but before the call to Invoke(). // Note: Most of our code does not check for this race condition. It probably should. // This probably doesn't happen very often. } } else if (!control.IsDisposed) code(); } } }