0

Ich möchte eine Methode zum Aktualisieren eines Textfelds mit Nachrichten als Statusprotokoll verfügbar machen. Ich würde gerne die AppendText-Methode verwenden, aber ich habe ein seltsames Problem mit mehreren Threads, wenn ich sie benutze. Ich bin in der Lage, neue Nachrichten durch Verkettung ganz gut anzuhängen. Das Problem stellt sich selbst dar, da das Textfeld nicht angezeigt wird, und dann wird der Cross Thread-Zugriffsfehler beim Schließen des Formulars angezeigt. Hier sind einige Beispiele von dem, was funktioniert und was nicht:Control.BeginInvoke funktioniert nicht mit TextBox.AppendText, Cross Threading

Arbeiten aber nicht AppendText wie es sei denn, zusätzliche Schritte unternommen werden, die das letzte Mittel ist:

Public Sub AddMessage2(ByVal newMessage As String) 
    If TextBoxStatus.InvokeRequired Then 
     TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.Text = TextBoxStatus.Text & newMessage & ControlChars.CrLf) 
    Else 
     TextBoxStatus.Text = TextBoxStatus.Text & newMessage & ControlChars.CrLf 
    End If 
End Sub 

Was ich möchte verwenden, aber nicht funktioniert:

Public Sub AddMessage(ByVal newMessage As String) 
    If TextBoxStatus.InvokeRequired Then 
     TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.AppendText(newMessage)) 
    Else 
     TextBoxStatus.AppendText(newMessage) 
    End If 
End Sub 

Zusätzliche Informationen und Updates: Zunächst entschuldige ich mich für wahrscheinlich nicht genügend Informationen im Voraus liefern.

Mindestens ein Teil des Problems scheint die Form zu Instanziieren und Aufrufen AddMessage(newMessage) vor Show() Aufruf, da der folgende Code funktioniert:

Public Sub AddMessage(ByVal newMessage As String) 
    If Me.Created Then 
     If TextBoxStatus.InvokeRequired Then 
      TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.AppendText(newMessage)) 
     Else 
      TextBoxStatus.AppendText(newMessage) 
     End If 
    End If 
End Sub 

Ich kann immer etwas tun, wie die folgenden, aber ich möchte, was auf geht :)

Private backLog As String = "" 
Public Sub AddMessage(ByVal newMessage As String) 
    If Me.Created Then 
     If TextBoxStatus.InvokeRequired Then 
      TextBoxStatus.BeginInvoke(Sub() TextBoxStatus.AppendText(backLog & newMessage)) 
     Else 
      TextBoxStatus.AppendText(backLog & newMessage) 
     End If 
     backLog = "" 
    Else 
     backLog &= newMessage 
    End If 
End Sub 

auch dies halte ich nicht sehr elegant sein ... vor allem, wenn ich log Größenbeschränkungen

+0

Unter normalen Umständen sollte Ihr Code funktionieren. Starten Sie den sekundären Thread, der "AddMessage" in dem Formular "Sub New" oder einem anderen Punkt aufruft, so dass das Handle "TextBoxStatus" noch nicht erstellt worden ist? Was passiert in dir? Fügen Sie 'If Not TextBoxStatus.IsHandleCreated Then Exit Sub' als erste Anweisung in' AddMessage' hinzu? – TnTinMn

+0

@TnTinMn Das Formular wurde noch nicht angezeigt, also bin ich sicher, dass Sie Recht haben. Ich wollte das Formular erstellen, ohne es anzuzeigen, bis der Benutzer es aus einem Menü öffnet. Ich werde nach, wie ich das tun kann, aber wenn Sie wissen, von der Spitze Ihres Kopfes wäre das toll :) Danke nochmal – Jon

+0

Hat mein Vorschlag oben zu beenden, wenn das Handle nicht erstellt wird, lösen Sie den Cross-Thread-Fehler ? Wenn ja, poste ich einen Hack, um den Text zu puffern, bis das Handle erstellt wird. Es wird aber nicht schön sein. – TnTinMn

Antwort

0
hinzufügen

Ich würde dies vorschlagen:

Public Sub AddMessage(ByVal newMessage As String) 
    If TextBoxStatus.InvokeRequired Then 
     TextBoxStatus.BeginInvoke(New Action(Of String)(AddressOf AddMessage), newMessage) 
    Else 
     TextBoxStatus.AppendText(newMessage) 
    End If 
End Sub 
+1

Macht das wirklich einen großen Unterschied? –

+0

Ich hatte das gleiche Problem. Ich habe meinen Beitrag aktualisiert und danke anderen für Kommentare. – Jon

+0

Ich meinte, IT hatte das gleiche Problem mit Bezug auf die obige Antwort, aber danke, dass Sie sich die Zeit genommen haben, einen Vorschlag zu machen. – Jon

Verwandte Themen