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
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
@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
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