Drydo's Blog

Teenager of the Internet

This blog hosted by:
http://blogs.vbcity.com
  Home :: Syndication  :: Login   Community Forums   :: vbCity.com   :: DevCity.NET  

WooHoo - back into actually doing some development after a stint doing some Flash Actionscript work and conducting a 4 week testing phase (possibility one of my favourite tasks).

Anyhoo, let's say you're trying to update a UI element from the non-UI worker thread using similar code to the following...

Code CopyHideScrollFull
' Single form, one button called 'butExecute' and one label called 'lblTime'
Private Sub butExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butExecute.Click
Dim t As New Threading.Thread(AddressOf UpdateTime)
t.Start()
End Sub
Private Sub UpdateTime()
' Updates the label with the appropriate Now time
Me
.lblTime.Text = Now.ToString
End Sub
. . .

When you clicked the button you would get a message along the following lines of...

"Cross-thread operation not valid: Control 'lblTime' accessed from a thread other than the thread it was created on."

...which basically means you cannot call any UI related methods / properties on any controls unless the call is made from the thread that created the control in the first place. So, the way to get around this would be to create a delegate that would invoke the method 'UpdateTime' on the UI thread, e.g. (my quick implementation)...

Code CopyHideScrollFull
Private Delegate Sub UpdateTimeDelegate()
Private Sub butExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butExecute.Click
Dim t As New Threading.Thread(AddressOf SafeUpdateTime)
t.Start()
End Sub
Private Sub SafeUpdateTime()
' Are we running on the main UI thread
If
Me.InvokeRequired Then
' If not, create a new delegate and invoke the method
Me
.Invoke(New UpdateTimeDelegate(AddressOf SafeUpdateTime))
Else
' We're running on the main UI thread so...
' Updates the label with the appropriate Now time
Me
.lblTime.Text = Now.ToString
End If
End Sub
. . .

Here we check whether we are running on the UI thread (using Me.InvokeRequired) and if are not we invoke the method on the UI thread.

However, there is a simplier way to do this without declaring an actual delegate - by creating an MethodInvoker object...

Code CopyHideScrollFull
Private Sub butExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butExecute.Click
Dim t As New Threading.Thread(AddressOf SafeUpdateTime)
t.Start()
End Sub
Private Sub SafeUpdateTime()
' Are we running on the main UI thread
If
Me.InvokeRequired Then
' If not, create a new delegate and invoke the method
Me
.Invoke(New MethodInvoker(AddressOf SafeUpdateTime))
Else
' We're running on the main UI thread so...
' Updates the label with the appropriate Now time
Me
.lblTime.Text = Now.ToString
End If
End Sub
. . .

Basically, the MethodInvoker class is intended to provide an accessible delegate object (without parameters) when you don't want to create the delegate yourself. Useful? Well, as daft as it sounds - yeah it is, and as a OO developer I always feel twitchy when copying/pasting/replacing parameterless delegate definitions.

HTH - M

posted on Wednesday, April 18, 2007 9:40 AM

Feedback

# re: Goodbye Parameterless Delegate Definitions - Hello MethodInvoker! 4/9/2008 6:18 AM Bryan
Very Cool ! Thanks!-- I was curious why one would use the MethodInvoker rather than creating Public Delegate Function X

Post Feedback

Title:
Name:
Url:
Comments: 
Protected by Clearscreen.SharpHIPEnter the code you see: