Eccolo in VB.net, molto simile alla risposta di Samuele. Ho quattro sovraccarichi a seconda che si voglia una subroutine o una funzione e se ci sia o meno un parametro. Sarebbe facile aggiungere più sovraccarichi per più parametri. VB.Net è in grado di dedurre i tipi.
Module ISynchronizeInvokeExtensions
Public Delegate Function GenericLambdaFunctionWithParam(Of InputType, OutputType)(ByVal input As InputType) As OutputType
Private Delegate Function InvokeLambdaFunctionCallback(Of InputType, OutputType)(ByVal f As GenericLambdaFunctionWithParam(Of InputType, OutputType), ByVal input As InputType, ByVal c As System.ComponentModel.ISynchronizeInvoke) As OutputType
Public Function InvokeEx(Of InputType, OutputType)(ByVal f As GenericLambdaFunctionWithParam(Of InputType, OutputType), ByVal input As InputType, ByVal c As System.ComponentModel.ISynchronizeInvoke) As OutputType
If c.InvokeRequired Then
Dim d As New InvokeLambdaFunctionCallback(Of InputType, OutputType)(AddressOf InvokeEx)
Return DirectCast(c.Invoke(d, New Object() {f, input, c}), OutputType)
Else
Return f(input)
End If
End Function
Public Delegate Sub GenericLambdaSubWithParam(Of InputType)(ByVal input As InputType)
Public Sub InvokeEx(Of InputType)(ByVal s As GenericLambdaSubWithParam(Of InputType), ByVal input As InputType, ByVal c As System.ComponentModel.ISynchronizeInvoke)
InvokeEx(Of InputType, Object)(Function(i As InputType) As Object
s(i)
Return Nothing
End Function, input, c)
End Sub
Public Delegate Sub GenericLambdaSub()
Public Sub InvokeEx(ByVal s As GenericLambdaSub, ByVal c As System.ComponentModel.ISynchronizeInvoke)
InvokeEx(Of Object, Object)(Function(i As Object) As Object
s()
Return Nothing
End Function, Nothing, c)
End Sub
Public Delegate Function GenericLambdaFunction(Of OutputType)() As OutputType
Public Function InvokeEx(Of OutputType)(ByVal f As GenericLambdaFunction(Of OutputType), ByVal c As System.ComponentModel.ISynchronizeInvoke) As OutputType
Return InvokeEx(Of Object, OutputType)(Function(i As Object) f(), Nothing, c)
End Function
End Module
Usage (eseguire questo in un BackgroundWorker):
InvokeEx(Sub(x As String) Me.Text = x, "foo", Me) 'set form title to foo
InvokeEx(AddressOf MsgBox, Me.Text, Me)
InvokeEx(Sub() Me.Text &= "!", "foo", Me) 'append "!" to form title
InvokeEx(AddressOf MsgBox, Me.Text, Me)
Dim s As String = InvokeEx(Function() Me.Text, Me) & "bar" 'get form title to backgorundworker thread
InvokeEx(AddressOf MsgBox, s, Me) 'display the string from backgroundworker thread
Si noti che la documentazione che circonda Invoke () su Control sono in realtà piuttosto sottili.Non credo che una classe generica sia sufficiente per il controllo a causa dell'interazione con IsHandleCreated e IsDisposed (a meno che non si controllino sempre i primi in SafeInvokeDelegate). (http://stackoverflow.com/questions/714666/) –
Grazie per aver condiviso questo corso. Mi ha aiutato a risolvere i miei problemi .. –