2017-02-21 13 views
-1

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

Я в основном хочу добавить некоторые тексты к элементу 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#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, но весь код в одном классе 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 
+0

Вы можете передать форму в качестве параметра методу 'count'. –

+0

Я уже пробовал этот путь. Но доступ к элементам из другого потока напрямую не рекомендуется, и я знаю, почему! Мой проект должен добавить текст более 200 раз, и приложение перестает отвечать и разбивается, когда я передаю форму как параметр, потому что форма запускается на нем собственной нитью. –

+0

Доступ к настраиваемому методу через форму должен быть настолько длинным, чтобы этот метод вызывал доступ к элементам пользовательского интерфейса. –

ответ

2

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

В вашей форме

Dim MyClass as Class1 
MyClass = New Class1(Me) 

In You r класс

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 
+1

Отлично! Это сработало! Я уже пытался передать параметр Form как параметр, но забыл вызвать тот же метод для добавления текста, вместо этого я обращался к элементу с помощью Parent_From.txtLogger.AppendText («что-то»). Большое вам спасибо! –