Have you ever written a multi-threaded application in .NET? If you have, chances are, you think that making thread-safe calls to update your UI is, well, really annoying and verbose at best.
The issue is that every time you are doing work in a thread other
than your UI thread, and then need to update the UI from said thread,
you need to create a delegate pattern in order to do so without getting
an InvalidOperationException.
Threads are nice when you need to do stuff in the background without
causing your application to hang. Often you want to show the progress of
the load that is being handled. In many occasions, that's a progressbar
but in some you want to show in detail what is being done. In the first
situation where it is only needed to update a progress bar, a
backgroundworker can be used. The background worker sends thread safe
events. In that event, you can update your progress bar. In the other
situations where you want to show more information of what is being
done, you need to call the form from within the other thread. If you do
that, you will get an invalid crossthreadcall exception.
The extension methods are as follows:
public static TResult SafeInvoke(this T isi, Func call) where T : ISynchronizeInvoke
{
if (isi.InvokeRequired) {
IAsyncResult result = isi.BeginInvoke(call, new object[] { isi });
object endResult = isi.EndInvoke(result); return (TResult)endResult;
}
else
return call(isi);
}
public static void SafeInvoke(this T isi, Action call) where T : ISynchronizeInvoke
{
if (isi.InvokeRequired) isi.BeginInvoke(call, new object[] { isi });
else
call(isi);
}
This is cool. So now if I want to set the value of a progress bar:
progressBar1.SafeInvoke(b => b.Value = progress);
Or if i want to simply call a method in my UI thread from another:
formInstance.SafeInvoke(f => f.myFormMethod("parameter1","parameter2"));
And finally, grabbing text/value from a control in your UI thread is one line too:
string textBoxText = txtBox1.SafeInvoke(f => f.txtBox1.Text);
Comments
Post a Comment