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
Roy, your formatting is a little weird???
Jonathan, how do you mean? looks fine in IE..
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.
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
Tony: I meant that that there will be an unecessary call
to "Invoke" if
"displayError2" is called by the main
GUI thread.
Roy,
Is the No.3 approach actually used by Microsoft at all?
Is this pattern present in any of their C# examples?
Sam
Sambo - Haven't seen this used anywhere in the docs or
samples. Surprised?
Hi Roy.
Thanks for the confirmation.
Regards, Tony.
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.
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.
Sorry about the late comments but what about this
method.
This has the added benefit of removing the need for the
delegate declaration.
Cheers
JB
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.