The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

My blog has moved. You can view this post at the following address: http://www.osherove.com/blog/2006/3/1/the-3-ways-to-create-a-thread-safe-gui-with-net-20-with-one.html
Published Wednesday, March 01, 2006 4:13 AM by RoyOsherove
Filed under:

Comments

Wednesday, March 01, 2006 8:19 AM by Urs

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

hm, at least the first example is perfectly possible in VB.NET 2005:

Private Delegate Sub Func(Of T)(ByVal parm As T)

Private Sub DisplayError(ByVal message As String)
If InvokeRequired Then
Dim del As New Func(Of String)(AddressOf DisplayError1)
del.Invoke(message)
Return
End If

ErrorDisplay.Show(message)
End Sub

AFAIK, there are no anonymous delegates involved here, right?
Best regards,
Urs

Wednesday, March 01, 2006 10:23 AM by Jonathan de Halleux

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Roy, your formatting is a little weird???
Wednesday, March 01, 2006 11:28 AM by Roy Osherove

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Jonathan, how do you mean? looks fine in IE..
Wednesday, March 01, 2006 11:29 AM by Roy Osherove

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Urs: yes. You're right. I should have said "The last two" are not possible, not all of them. However, I don't like the furst way anyway, and was just using it as a jumping step to the better examples.
Thanks for the comment.
Roy.
Wednesday, March 01, 2006 1:24 PM by Stef Rave

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

You can also use the ThreadStart delegate from Stystem.Threading:

private void displayError2(string message)
{
Invoke(new ThreadStart(delegate
{
errorDisplay.Show(message);
}));
}

I saw that trick on Clemens Vasters blog
http://friends.newtelligence.net/clemensv/PermaLink,guid,4b9d14f4-a6e3-454b-bcaf-35cbd903d393.aspx
Friday, March 03, 2006 9:08 AM by Tony Day

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Hi Roy

Thanks for the article.

At the risk of exposing my lack of understanding I would like to ask the following :

In your description of the third (and preferred) option you describe an 'extra call to the "Invoke" method'.
This seems to suggest that a call to "displayError2" may result in more than one call to the "Invoke" method.
Is this was you meant ??
Or did you you mean (as I interpreted it) that there will be an unecessary call to "Invoke" if "displayError2" is called by the main GUI thread ??

Sorry if this seems pedantic but your answer will confirm that I have in fact understood (or not :-)

Regards, Tony
Saturday, March 04, 2006 5:24 AM by Roy Osherove

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Tony: I meant that that there will be an unecessary call to "Invoke" if "displayError2" is called by the main GUI thread.
Saturday, March 04, 2006 11:40 AM by Samboy LIms

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Roy,

Is the No.3 approach actually used by Microsoft at all? Is this pattern present in any of their C# examples?

Sam
Saturday, March 04, 2006 12:49 PM by Roy Osherove

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Sambo - Haven't seen this used anywhere in the docs or samples. Surprised?
Monday, March 06, 2006 2:43 AM by Tony Day

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Hi Roy.

Thanks for the confirmation.

Regards, Tony.
Wednesday, March 08, 2006 8:51 AM by Ian Griffiths

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Why are you using Invoke as opposed to BeginInvoke?

Invoke makes the non-UI thread wait until the UI thread has finished calling your method.

This is more prone to deadlock than BeginInvoke, which doesn't block. E.g., if your UI thread and worker thread ever use some shared resource, then that will need to be protected by some kind of locking mechanism. If your worker thread is in posession of that lock at the point at which it calls Invoke (easily done if you ever end up calling Invoke inside of an event handler - who knows what locks are being held by whatever thread called your event handler?) and the UI thread was trying to acquire the lock, you've just frozen your process terminally.

With Control.BeginInvoke, this situation never arises.

Always prefer BeginInvoke. If you have a really good reason for wanting to use Invoke instead, then fix your design so you can use BeginInvoke instead. :) If you really can't do that, then consider using Invoke, but put big flashing warning comments around it indicating that it's a potential deadlock hazard, and needs very close attention from anyone modifying the code in the future.
Monday, March 13, 2006 7:01 AM by Roy Osherove

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Ian - thanks for writing this comment. It certainly is something I had not considered as a problem, but will certainly have to consider it once more.
I'm not inclined to use BeginInvoke mainly because it really does do its work in an async manner.
Plenty of times when you do GUI code, you're assumign that the GUI code is indeed blocking.
But, that's just a feeling,. I'll check it out more seriously and write down what I find.
Thursday, May 25, 2006 1:20 AM by john B

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Sorry about the late comments but what about this method.

private void displayError2(string message)
{
 Invoke(new MethodInvoker(
   delegate
   {
     errorDisplay.Show(message);
   }
   ));
}

This has the added benefit of removing the need for the delegate declaration.

Cheers
JB
Thursday, May 25, 2006 4:02 PM by HL

# re: The 3 ways to create a Thread-Safe GUI with .NET 2.0, with one clear winner.

Has anyone figured out the thread management related to data binding? I have seen many posts on using the Invoke method to directly update controls, but I have not seen antyone delve into the internals of what threads are executing when a data bound property on an object changes. In my testing it appears that the data binding related events are occurring on the background thread, at least through the BindingManagerBase CurrentChanged Event. Note that the control events (TextCHanged, Invalidated) occur on the correct thread.

HL
Saturday, August 19, 2006 8:47 AM by Nblog (a shadow copy)

# Thread-Safe GUI

Roy Osherove na swoim blogu pokazuje sposoby na implementację metod dostępowych do elementów okna w Windows...

Sunday, January 21, 2007 8:57 AM by Tim Van Wassenhove » About Thread-Safe GUI…

# Tim Van Wassenhove » About Thread-Safe GUI…

# Thead Safe Calls To Windows Forms in Visual Studio 2005 at clifgriffin > blog

Pingback from  Thead Safe Calls To Windows Forms in Visual Studio 2005 at  clifgriffin > blog

Monday, February 04, 2008 8:17 PM by egeye

# .NET 2.0 中,两种如何创建一个线程安全的 UI 的方法

刚刚编写了线程安全的代码,该方法示例执行 Windowns Forms Event Handler 跨线程 UI 调用,BindXmlDocumentToTreeView 是一个绑定 Xml 到一个 TreeView 控件的方法,其可以很好的工作于不同的线程。它首先检查 Control(TreeView)的 InvokeRequired 属性,以判断是否是与 UI 线程不同的线程调用,然后使用 TreadPool 工具,并借助 .Net 2.0 中的匿名代理,使用 TreadStart 委托。

Wednesday, April 02, 2008 2:40 AM by zyly2

# 一个多线程图片抓取.net类库的实现(一)

其实现在网上内容抓取的工具和代码也比较多了,我查了看了看,网上很多都是讲述如何利用xmlhttp(ajax)方式来对网页的内容来进行抓取,因为利用javascipt很容易对抓取的内容进行分析。