I have seen Microsoft suggest using a custom Delegate in the InvokeRequired pattern
But I can't figure out why one wouldn't just save the trouble of defining the delegate when doing something as simple as setting a control property. I'm referring to Option 1 below which just uses the delegate Action(Of String) instead of a custom delegate.
' Option 1
Private Sub setLabelWorkingText(ByVal [text] As String)
If Me.lblWorking.InvokeRequired Then
Me.Invoke(New Action(Of String)(AddressOf setLabelWorkingText), [text])
Else
Me.lblWorking.Text = [text]
End If
End Sub
' Option 2
Private Delegate Sub setLabelWorkingTextDelegate(ByVal [text] As String)
Private Sub setLabelWorkingTextWithDel(ByVal [text] As String)
If Me.lblWorking.InvokeRequired Then
Me.Invoke(New setLabelWorkingTextDelegate(AddressOf setLabelWorkingTextWithDel), [text])
Else
Me.lblWorking.Text = [text]
End If
End Sub
I understand one difference to be that arguments can't be passed ByRef using Action and Func, but a custom delegate can specify ByRef arguments. Are there any other differences between the two?
An Action is essentially a custom delegate that's defined by way of a generic. I'm guessing the reason it's not specified in the pattern you linked to is that both the pattern and the Action delegate were developed/released at the same time, and the people developing the pattern and documentation may not have been familiar with the Action generic at the time of release. You'll notice that Action is used more often in examples and patterns for later releases of the Framework, as it gained acceptance.
Also, with regards to your comment on ByRef arguments to Action and Func, this is correct, but it's also trivial to implement a custom generic Action-like class that accepts parameters ByRef, as in:
Public Delegate Sub ActionByRef(Of T)(ByRef ref As T)
Sub Main()
Dim sMyString As String = "Hello World"
Dim actTrim As New ActionByRef(Of String)(AddressOf TrimFirst)
actTrim.Invoke(sMyString)
Console.WriteLine(sMyString) 'prints "ello World"
Console.ReadLine()
End Sub
Sub TrimFirst(ByRef s As String)
s = s.Substring(1)
End Sub
Its definitely simpler to write an Action compared to a Delegate if you can get away with it.
An Action just allows you to "pass a method as a parameter without explicitly declaring a custom delegate." Source
When you pass a lambda function I think you're adding one more line to the call stack, but meh.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With