Ici, c'est dans VB.net, très similaire à la réponse de Samuel. J'ai quatre surcharges selon que vous voulez un sous-programme ou une fonction et si oui ou non il y a un paramètre. Il serait facile d'ajouter plus de surcharges pour plus de paramètres. VB.Net est capable de déduire les types.
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
Utilisation (exécuter ce dans 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
Notez que la documentation entourant Invoke () sur le contrôle sont en réalité assez subtiles.Je ne crois pas qu'un cours générique soit suffisant pour Control à cause de l'interaction avec IsHandleCreated et IsDisposed (à moins que vous ne vérifiiez toujours ceux-ci en premier dans votre SafeInvokeDelegate). (http://stackoverflow.com/questions/714666/) –
Merci d'avoir partagé cette classe. A m'a aidé à résoudre mes problèmes .. –