Comment convertir un appel de délégué en ligne lorsque l'on convertit du code CSharp en VB.Net ?
Au départ, il s'agit par exemple de corriger l'erreur classique inter-threads :
"Opération inter-threads non valide : le contrôle 'lblStatus' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé."
Le code en C# est le suivant : www.codeproject.com/KB/cs/ApplicationIdle.aspx
private void App_Idle(ApplicationIdleTimer.ApplicationIdleEventArgs e) { this.lblStatus.BackColor = Color.Green; this.lblStatus.Text = string.Format("Idle: {0}s", e.IdleDuration.TotalSeconds.ToString("0")); }
La solution en C# est d'utiliser un délégué, ici déclaré directement en ligne dans le code :
private void App_Idle(ApplicationIdleTimer.ApplicationIdleEventArgs e) { Invoke((MethodInvoker) delegate { lblStatus.BackColor = Color.Green; lblStatus.Text = string.Format("Idle: {0}s", e.IdleDuration.TotalSeconds.ToString("0")); }); }
Lorsque l'on utilise le convertisseur de code de C# en VB.Net, on obtient un code qui ne compile pas :
www.developerfusion.com/tools/convert/csharp-to-vb/
Invoke(DirectCast(Function() Do lblStatus.BackColor = Color.Green lblStatus.Text = String.Format("Idle: {0}s", e.IdleDuration.TotalSeconds.ToString("0")) End Function, MethodInvoker))
Voici comment il faut corriger ce code :
Il faut d'abord déclarer un délégué perso.:
Public Delegate Function myDelegate( _ ByVal e As ApplicationIdleTimer.ApplicationIdleEventArgs) As Integer
Ensuite il faut déclarer une fonction perso. qui sera appelée par le délégué :
Function MyFunctionDelegate(ByVal e As ApplicationIdleTimer.ApplicationIdleEventArgs) As Integer lblStatus.BackColor = Color.Green lblStatus.Text = String.Format("Idle: {0}s", e.IdleDuration.TotalSeconds.ToString("0")) Return 0 End Function
Et enfin il faut faire appeler la fonction perso. via le délégué depuis la fonction principale qui est appelée par l'autre thread, de sorte qu'au final, ce sera bien le thread associé à la fenêtre principale qui affichera ce qu'il faut :
Private Sub App_Idle(ByVal e As ApplicationIdleTimer.ApplicationIdleEventArgs) Dim myDel As New myDelegate(AddressOf MyFunctionDelegate) Dim args() As Object = {e} MyBase.Invoke(myDel, args) End Sub