The lazy/dangerous way to get around this is to set the Control.CheckForIllegalCrossThreadCalls on the owner/parent control to false.
If your absolutely sure of what you're doing it's ok. But still not advisable.
The right way is to perform a check on the InvokeRequired property of the control and if so Invoke/BeginInvoke (synchronously or asynchronously it's up to you) the method via a delegate.
This is fine but if you have to expand this along your code it gets kind of boring.
If you read my previous article I've talked about a cool .NET feature called Extension Methods.
What I'll show you next is a very handy peace of code that you can put in a library and reuse in any app you do.
using System; using System.Windows.Forms; namespace Extensions { public delegate void UIDelegate(); /// <summary> /// Control class extension methods /// </summary> static public class ControlExtensions { /// <summary> /// Performs a UI Thread safe Control.Invoke. /// </summary> /// <param name="control">Target control.</param> /// <param name="dlg">delegate method to be invoked.</param> static public void SafeInvoke(this Control control, UIDelegate dlg) { if (control.InvokeRequired) { control.Invoke(dlg); return; } dlg.Invoke(); } /// <summary> /// Performs a UI Thread safe Control.BeginInvoke. /// </summary> /// <param name="control"></param> /// <param name="dlg">delegate method to be invoked asynchronously.</param> static public void BeginSafeInvoke(this Control control, UIDelegate dlg) { if (control.InvokeRequired) { control.BeginInvoke(dlg); return; } dlg.Invoke(null, null); } } }
Basically I've extended the Control type class and "added" 2 new methods.
To perform a thread safe operation inside, for example a form, we only have to add our Extensions namespace and call the code like this.
this.SafeInvoke(delegate { /// do stuff... });
That's it. It's a pretty clean away of performing operations over controls in a thread safe manner.
;-)
No comments:
Post a Comment