如何将文本设置为在另一个线程中创建的元素

How to set text to element created in another thread

在开始之前,我知道这个问题已经有了很多答案,但让我解释一下发生了什么。

我基本上想将一些文本附加到 RichTextBox 元素,它对我来说就像一个记录器,用于通知用户文件处理中的每个操作,但文本是通过 for 循环附加到 RichTextBox 的,如果我在相同的 class "Form1.vb" 中执行此循环 UI 冻结,直到循环完成。

我决定 运行 在一个单独的线程中循环以避免 UI 冻结,我的问题就是从这里开始的。

Form1.vb

Imports System.Threading


Public Class Form1

    Dim myThread As Thread

    Private Sub appendMyText()
        ' Cross-thread operation not valid: Control txtLogger accessed from a thread other than the thread it was created on.
        txtLogger.AppendText("Hello World" & vbNewLine)
    End Sub

    Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
        myThread = New Thread(New ThreadStart(AddressOf appendMyText))
        myThread.Start()
    End Sub

End Class

我无法从另一个线程访问 txtLogger 元素,所以我尝试了 MSDN 示例 https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2

它向我展示了如何使用委托访问进行线程安全调用的元素。

所以我编辑的代码是

Form1.vb

Imports System.Threading

Public Class Form1

    Dim myThread As Thread
    Delegate Sub AppendMyText(ByVal text As String)

    ' Add the text to RichTextBox
    Private Sub addText(ByVal txt As String)
        If txtLogger.InvokeRequired Then
            Dim myDelegate = New AppendMyText(AddressOf addText)
            Me.Invoke(myDelegate, {txt})
        Else
            txtLogger.AppendText(txt)
        End If
    End Sub

    ' Call the method that add text to RichTextBox
    Private Sub threadSafe()
        Me.addText("Hello World" & vbNewLine)
    End Sub

    Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
        myThread = New Thread(New ThreadStart(AddressOf threadSafe))
        myThread.Start()
    End Sub

End Class

代码确实是这样工作的,文本附加到 RichTextBox,但所有代码都在同一个 class Form1.vb

在我原来的项目中,for循环是在另一个class中执行的,我在这里将其命名为"Class1.vb"。

这就是代码示例

Class1.vb

Public Class Class1

    Public Sub count()
        Dim i As Integer

        For i = 0 To 100
            ' this method will be executed by thread "myThread"
            ' how to append text to txtLogger from here?
            Debug.WriteLine("Index: {0}", i)
        Next
    End Sub

End Class

将表单引用传递给 class

在你的表单中

Dim MyClass as Class1
MyClass = New Class1(Me)

在你的class

Public Class Class1

     Private Parent_From as Form1
     Public Sub New(Parent as Form1)
           Parent_From = Form
     End sub
     Public Sub count()
        Dim i As Integer
        For i = 0 To 100
            ' this method will be executed by thread "myThread"
            Parent_Form.addTExt("Whatever")
            Debug.WriteLine("Index: {0}", i)
        Next
    End Sub
End CLass