2009-08-01 7 views
1

Momentan habe ich ein komisches Problem, das ich einfach nicht verstehe. Ich habe eine einfache GUI, mit einer Taste & eine Richitbox. Ich habe einen Async-Socket ausgeführt, ich erhalte einige Daten über das Netzwerk, das ich auf die GUI (Richeditbox) drucken möchte. Der asynchrone Socket wird gestartet, wenn der Benutzer auf die Schaltfläche klickt. Also, wenn ich die Netzwerkdaten empfangen nenne ich eine Funktion, die die Daten druckt, hier, wie es aussieht (in form1 Klasse):Windows Forms mit asynchronem Socket; keine Textausgabe

Public Sub AddText(ByVal text As String) 

Try 

    Console.WriteLine(text) 
    RichTextBox1.AppendText(text) 
    RichTextBox1.AppendText(vbNewLine) 

Catch e As Exception 
    Console.WriteLine(e.ToString()) 
End Try 

End Sub 

Dann einfach ich Form1.AddText(..) aus meinem Netzwerk-Klasse oder ein Modul (tut es Sache ?). Das Problem ist, dass nichts in der Richeditbox erscheint, obwohl die AddText Funktion aufgerufen wird, keine Ausnahmen, keine Fehler, einfach nichts. Ich habe mit dem Debugger durchgeschaut, und "text" enthielt die Daten, die es zu drucken hatte, aber einfach nichts erscheint .. Wer hat eine Idee?

Antwort

1

Wenn der Socket auf einem anderen Thread ausgeführt wird (was natürlich darauf zurückzuführen ist, dass er asynchron ist), müssen Sie möglicherweise InvokeRequired verwenden, damit RichTextBox den Text anzeigt. Ich hatte ein ähnliches Problem mit einem Listener auf einem asynchronen seriellen Port-Listener.

+0

Ich habe es schon probiert, aber dasselbe Ergebnis:/ Privat Delegate Sub dlgUpdate (ByVal Text As String) Sub Updatelog (ByVal Text As String) Wenn RichTextBox1.InvokeRequired = True Then Dim d As New dlgUpdate (AddressOf Updatelog) RichTextBox1.Invoke (d, Text) Else RichTextBox1.AppendText (Text) End If End Sub Hinweis: die Updatelog Funktion funktioniert, wenn ich es aus dem gUI-Thread aufrufen, so dass ich denke, es ist damit verwandt, aber ich sehe nicht, warum es nach der Verwendung von InvokeRequired immer noch nicht funktioniert. –

+0

uh .. das sieht hässlich aus, kann nicht einmal den Code im Kommentar sehen, ich nahm den Code von: http://www.vbdotnetforums.com/asp-net-data-access/19740-how-use-invokerequired .html –

+0

Das mag ein dummer Vorschlag sein, aber wenn der UI-Thread gesperrt ist, könnten Sie immer versuchen, eine Application.DoEvents() nach dem Anhängen des Textes einzuwerfen. – David

1

Ich bin mir ziemlich sicher, David hat Recht. Hier ist ein Beispiel.

Der Deal ist, dass die Steuerelemente für den Thread aktualisiert werden müssen, auf dem sie erstellt wurden. Es scheint, als ob die AddText() - Routine im Kontext des Threads des asynchronen Sockets aufgerufen wird. Die AddText() - Routine verhält sich wie eine rekursive Funktion. Wenn sie das erste Mal aufgerufen wird, ist die InvokeRequired-Eigenschaft wahr. Dies wird dazu führen, dass es erneut über den Invoke() - Aufruf aufgerufen wird, der dafür sorgt, dass die Daten an den richtigen Thread gemarshallt werden. Wenn InvokeRequired das zweite Mal aufgerufen wird, ist InvokeRequired false und das Steuerelement wird aktualisiert.

+0

Hm danke, funktioniert immer noch nicht. Ich habe mit dem Debugger überprüft und jedes Mal, wenn die Funktion aufgerufen wurde InvokeRequired war "falsch". Und ja, es hängt damit zusammen, denn beim Debuggen sehe ich, dass die addText-Funktion nicht von "MainThread" aufgerufen wird. Danke für Ihre Hilfe! –

+0

Ich meinte, dass die AddText-Funktion funktionierte nur, wenn es von der MainThread aufgerufen wird, z. B. auf Form1_Load. –

0

Behoben. Ich konnte Form1 nicht verwenden, um die Funktionen aufzurufen, weil es ein Typ ist, der wie eine neue Variable mit eigenem Speicher ist, da es ein Diff-Thread ist. Als ich also InvokeRequired überprüfte, sagte es false, weil Form1 zu diesem Thread gehört und daher kein Text angezeigt wurde, weil ich das Formular nicht einmal gesehen habe. Also habe ich eine globale Variable wie Public myForm As Form1 erstellt und myForm in Form1_Load Form1 zugewiesen.