Недопустимая операция перекрестного потока

#vb.net #multithreading

#vb.net #многопоточность

Вопрос:

я пытаюсь получить доступ к расширенному текстовому полю в другой форме, используя для этого следующий код:

 Private Delegate Sub StringDelegateChat(text As String, window As ChatWindow)
    Private Sub AppendTextChatWindows(text As String, window As ChatWindow)
        Try              
            If window.RichTextBox1.InvokeRequired Then
                window.Invoke(New StringDelegateChat(AddressOf AppendTextChatWindows), text, window)
            Else
                window.RichTextBox1.AppendText(text)
                window.RichTextBox1.SelectionStart = window.RichTextBox1.Text.Length
                window.RichTextBox1.ScrollToCaret()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        End Try
    End Sub
  

но я получаю ошибку недопустимости операции с перекрестным потоком, я думаю, это происходит потому, что она пропускает window.invoke часть инструкции if. я также попытался заменить If window.RichTextBox1.InvokeRequired Then to If InvokeRequired Then , но он попадает в цикл continues и выдается ошибка переполнения стека.

Спасибо, Хоулахан

Комментарии:

1. Пробовал уже окно. Вместо window требуется InvokeRequired. Требуется richTextBox1.InvokeRequired?

2. да, это просто переходит к else, а затем удаляет исключение :/

3. Вы абсолютно уверены, что дескриптор controls был создан? Даже если это так, возможно, не помешает перепроверить…

Ответ №1:

Я считаю, что в строке 5 window.Invoke следует изменить на window.RichTextBox1.Invoke .

 Private Delegate Sub StringDelegateChat(text As String, window As ChatWindow)
Private Sub AppendTextChatWindows(text As String, window As ChatWindow)
    Try
        If window.RichTextBox1.InvokeRequired Then
            window.RichTextBox1.Invoke(New StringDelegateChat(AddressOf AppendTextChatWindows), text, window)
        Else
            window.RichTextBox1.AppendText(text)
            window.RichTextBox1.SelectionStart = window.RichTextBox1.Text.Length
            window.RichTextBox1.ScrollToCaret()
        End If
    Catch ex As Exception
        MessageBox.Show(ex.ToString)
    End Try
End Sub
  

Ответ №2:

Вы пробовали:

     Private Sub AppendTextChatWindows(text As String, window As ChatWindow)
        Try              
            If window.RichTextBox1.InvokeRequired Then
                window.RichTextBox1.BeginInvoke(New StringDelegateChat(AddressOf AppendTextChatWindows), text, window)
                Exit Sub 
            Else
                window.RichTextBox1.AppendText(text)
                window.RichTextBox1.SelectionStart = window.RichTextBox1.Text.Length
                window.RichTextBox1.ScrollToCaret()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        End Try
    End Sub
  

По сути, я спрашиваю о BeginInvoke, а не о Invoke . Хотя я бы ожидал, как упоминалось в другом постере, что вы должны использовать то же самое, что вы проверяете на соответствие требуемому для вызова. (т.е. оба window.InvokeRequired и window.BeginInvoke или элемент управления)

Ответ №3:

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

В качестве решения вашей проблемы, работая с объектами, вы с меньшей вероятностью столкнетесь с проблемами с перекрестными потоками.