Best way to handle Control.InvokeRequired without duplicating code?

S

Samuel R. Neff

I'm trying to find a good way to handle Control.InvokeRequired without
duplicating four lines of code in every function/event. Typically
what I've seen in books is this:

If InvokeRequired Then
Invoke(new EventHandler(AddressOf thisFunc), new Object() { sender,
e})
Return
End If

At the start of every function. Is there a good way to extract these
four lines of code from the functions themselves? I figured I can
make an InvokeIfRequired function but I would still need three lines
in order to accomodate the Return.

The best I could come up with is to get at it from the sending side
and not the receiving side (code below) but that it feels like the
handler should be taking care of this and not the sender (ideally, the
framework would take care of it internally for events).

Also the downside to the sub I came up with is that you lose
compile-time checking on arguments.

other options?

Thanks,

Sam


Public Shared Sub SmartRaiseEvent( _
ByVal delegat As [Delegate], _
ByVal args As Object(), _
ByVal synchronous As Boolean)

For Each iDelegate As [Delegate] In _
delegat.GetInvocationList()

Dim target As Object = iDelegate.Target
If Not target Is Nothing AndAlso _
TypeOf target Is Control AndAlso _
DirectCast(target, Control).InvokeRequired Then

If synchronous Then
DirectCast(target, Control).Invoke(iDelegate, args)
Else
DirectCast(target, Control).BeginInvoke(iDelegate, args)
End If
Else
iDelegate.DynamicInvoke(args)
End If
Next
End Sub
 
P

Peter Huang [MSFT]

Hi

I think in common a class event is designed as three part.
1. the delegate function
2. the event of type with that delegate
3. a OnXXXX Function will which fired the event

So I think we can add the InvokeRequired code in the OnXXXX Function.

e.g.

Private Sub OnFilesFound(ByVal Sender As Object, _
ByVal e As System.EventArgs)
If Me.InvokeRequired Then
Dim del As New UpdateUIFilesFoundDelegate( _
AddressOf Me.UpdateUIFilesFound)
Me.BeginInvoke(del
Else
Me.UpdateUIFilesFound()
End If
End Sub

Asynchronous Execution in Visual Basic .NET
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechar
t/html/vbasync.asp

Also the SmartRaiseEvent you provided is somewhat a common method will will
raiseevent on all kind of event, so the compile time check will be missing,
as we have to use "ByVal args As Object()" similar declaration to pass
parameters.

Or I think we may have another idea that we can add a OnSafeXXXX fuction
will marshal the invoke call.
e.g.
Private Sub OnFilesFound(ByVal Sender As Object, _
ByVal e As System.EventArgs)
RaiseEvent FilesFound(Sender,e)
End Sub

Private Sub OnSafeFilesFound(ByVal Sender As Object, _
ByVal e As System.EventArgs)
If Me.InvokeRequired Then
'Invoke the OnFilesFound here
'Since the Sender and EventArgs has passed the compiling time
check, we just has the raiseevent call running on the UI thread just as we
do in the single thread program.
End If
End Sub

If you still have any concern, please feel free to post here.

Best regards,

Perter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top