2016-11-06 1 views
1

Ich schreibe eine VB-Formular-Anwendung, die den Standard-Ausgabestream eines Prozesses umleitet und es in einer Benutzeroberfläche verwendet.VB Formular Cross-Thread-Methode Aufruf mit Parametern

Ich habe Probleme beim Aufrufen von Methoden mit Parametern, die Steuerelemente im Formular vom OutputHandler-Sub aktualisieren.

kann ich eine Methode ohne Parameter aufrufen, so wie

Me.Invoke(New MyDelSub(AddressOf ServerStarted)) 

der gut arbeitet.

Und ein bisschen Googeln hat mir gesagt, dass ein Verfahren mit Parametern aufzurufen ich dies tun soll:

Dim del As JoinDelegate = AddressOf PlayerJoins 
del.Invoke(username) 

Mit diesen Delegierten und Verfahren Paar:

Private Delegate Sub JoinDelegate(ByVal username As String) 
Private Sub PlayerJoins(ByVal username As String) 
    PlayersBox.Items.Add(username) 
    'Do other stuff 
End Sub 

Aber dies erzeugt ein IllegalOperationException der Zum ersten Mal versucht die Methode, auf ein Steuerelement zuzugreifen.

+0

Die Frage wurde mehrmals gestellt und beantwortet. Zum Beispiel werfen Sie einen Blick auf diesen Beitrag: [Cross-Thread-Betrieb nicht gültig VB.NET] (http://stackoverflow.com/questions/1331009/cross-thread-operation-not-valid-vb-net). Die Verwendung von [Lambda Expressions] (https://msdn.microsoft.com/en-us/library/bb531253.aspx) zur Lösung des Problems kann jedoch syntaktisch interessant sein. –

+0

Ja, ich las ein paar von ihnen durch, konnte einfach nicht herausfinden, wie man das benutzt, um Parameter zu übergeben. Entschuldigung dafür, dumm zu sein;) – JHall

Antwort

1

1) Angenommen, Sie ein Verfahren wie dieses:

Public Sub DoSomething(value1 As String, value2 As String) 
    MessageBox.Show(String.Format("{0} {1}", value1, value2)) 
End Sub 

Sie können es nennen diese Art und Weise mit aufrufen:

Me.Invoke(Sub() DoSomething("Hello", "World!")) 

2) Wenn Sie Thread-sicher machen wollen Aufruf an ein Steuerelement können Sie die Methode auf diese Weise schreiben:

Public Sub AddItemToListBox1(item As String) 
    If (ListBox1.InvokeRequired) Then 
     ListBox1.Invoke(Sub() AddItemToListBox1(item)) 
    Else 
     ListBox1.Items.Add(item) 
    End If 
End Sub 

Dann ist es genug, um es in einem dem UI-Thread oder in einem anderen Thread einfach auf die gleiche Weise zu nennen:

würde
AddItemToListBox1("some item") 

Der Anruf fädeln werden sicher.

+0

Genau das, was ich wollte, kann nicht glauben, dass ich nicht gesehen habe, wie man das macht - verbrachte Stunden damit, mit Delegierten und allen Arten von Spaghetti-Code rumzualbern. Danke! – JHall

+0

Gern geschehen :) - Ich glaube, es ist der lesbarste und sauberste Weg. –

0

z.

Private Sub SetControlText(control As Control, text As String) 
    If control.InvokeRequired Then 
     control.Invoke(New Func(Of Control, String)(AddressOf SetControlText), control, text) 
    Else 
     control.Text = text 
    End If 
End Sub 

Rufen Sie diese Methode aus einem beliebigen Thread.

Verwandte Themen