JimNevado Ответов: 3

Исключение перекрестной резьбы


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

Что я уже пробовал:

Private Sub DataReceived(ByVal sender As System.Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort2.DataReceived


     Received_mega = SerialPort2.ReadExisting

     Book_CodeTextBox.Text = Received_mega

 End Sub

3 Ответов

Рейтинг:
2

OriginalGriff

Чтобы добавить к тому, что правильно говорит Ричард: причина, по которой вы получаете ошибку, заключается в том, что событие DataReceived не обрабатывается исходным потоком пользовательского интерфейса - как ясно из документации:

Событие DataReceived вызывается во вторичном потоке при получении данных из объекта SerialPort. Поскольку это событие возникает во вторичном потоке, а не в основном потоке, попытка изменить некоторые элементы в основном потоке, такие как элементы пользовательского интерфейса, может вызвать исключение потока. Если необходимо изменить элементы в основной форме или элементе управления, отправьте запросы на изменение обратно с помощью Invoke, который выполнит работу над соответствующим потоком.

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

В VB можно "обойти" это, добавив это в свой конструктор форм:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
Но гораздо, гораздо лучший способ сделать это-использовать Invoke для перемещения доступа к элементу управления обратно в поток пользовательского интерфейса, как описано в ссылке Ричарда.


Рейтинг:
0

phil.o

Вы должны вызвать обновление, так как поток, в котором выполняется ваш обработчик, похоже, не является потоком, создавшим элемент управления:

Private Sub DataReceived(ByVal sender As System.Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort2.DataReceived

     Received_mega = SerialPort2.ReadExisting

     Book_CodeTextBox.Invoke(New MethodInvoker(Sub() Book_CodeTextBox.Text = Received_mega), Nothing)

 End Sub