如何将文本设置为在另一个线程中创建的元素
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
在开始之前,我知道这个问题已经有了很多答案,但让我解释一下发生了什么。
我基本上想将一些文本附加到 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