Как установить текст для элемента, созданного в другой теме

Прежде чем начать, я знаю, что уже есть куча ответов на этот вопрос, но позвольте мне объяснить, что происходит.

Я в основном хочу добавить некоторые тексты к элементу RichTextBox, он служит мне как регистратор для информирования пользователя о каждом действии от обработки файла, но текст добавляется к RichTextBox через цикл for, и если я выполняю этот цикл в тот же класс "Form1.vb" пользовательский интерфейс останавливается до завершения цикла.

Я решил запустить цикл в отдельном потоке, чтобы избежать зависания пользовательского интерфейса, и именно здесь начинается моя проблема.

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

Он показывает мне, как получить доступ к элементу, выполняющему поточно-ориентированные вызовы, используя делегат.

Так что мой отредактированный код

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, но весь код находится в одном классе Form1.vb

В моем первоначальном проекте цикл for выполняется в другом классе, здесь я назову его "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

1 ответ

Решение

Передайте ссылку на форму в класс

В вашей форме

Dim MyClass as Class1
MyClass = New Class1(Me)

В вашем классе

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
Другие вопросы по тегам