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