VB.NET Многопоточность.Вызов invoke для UI Control из класса в отдельном файле класса - PullRequest
6 голосов
/ 13 мая 2011

Я уже несколько дней пытаюсь понять это и удивляюсь, если это что-то простое, я пропускаю или делаю совершенно неправильно.

Пример: Два файла - TestClass.vb, myForm.vb


TestClass.vb выглядит следующим образом:

Imports System.Threading

Public Class TestClass
    Private myClassThread As New Thread(AddressOf StartMyClassThread)

    Public Sub Start()
        myClassThread.Start()
    End Sub

    Private Sub StartMyClassThread()
        myForm.Msg("Testing Message")
    End Sub
End Class

myForm.vb - это базовая форма с элементом управления списком и кнопочным элементом управления, который называется соответственно Output и StartButton. Код за формой выглядит следующим образом:

Public Class myForm
    Private classEntity As New TestClass

    Private Sub StartButton_Click(ByVal sender As System.Object, _
                                  ByVal e As System.EventArgs) _
                              Handles StartButton.Click
        Msg("Start Button Pressed")
        classEntity.Start()
    End Sub

    Delegate Sub MsgCallBack(ByVal mesg As String)

    Public Sub Msg(ByVal mesg As String)
        If Output.InvokeRequired Then
            MsgBox("Invoked")
            Dim d As New MsgCallBack(AddressOf Msg)
            Invoke(d, New Object() {mesg})
        Else
            MsgBox("Not Invoked")
            mesg.Trim()
            Output.Items.Add(mesg)
        End If
    End Sub
End Class

Результат:

Приложение работает, без ошибок и исключений. Отображается список и кнопка «Пуск». Я нажимаю кнопку «Пуск», и в окне сообщения появляется сообщение «Не вызвано», как и ожидалось, и после нажатия кнопки «ОК» это поле сообщения «Нажата кнопка запуска» добавляется в элемент управления списка вывода. Сразу после этого всплывающее окно msgbox снова всплывает и говорит: «Не вызывается». Я ожидал, что «Вызван», поскольку отдельный поток пытается использовать элемент управления списка вывода. Конечно, это приводит к попытке Output.Items.Add, которая не дает видимого результата, так как поток не может напрямую обновлять элемент управления UI.

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

С уважением,

Lex

1 Ответ

3 голосов
/ 20 мая 2011

Проблема здесь в том, что вы вызываете функцию Msg не для экземпляра myForm, а как разделяемую функцию класса myForm.

Измените код в TestClass, добавив

Public FormInstance as myForm

и затем замените

myForm.Msg("Testing Message")

на

FormInstance.Msg("Testing Message")

Затем в StartButton_Click добавьте строку

classEntity.FormInstance = Me

, и вы получитеожидаемый результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...