Из статьи MSDN о SerialPort.DataReceived
"Событие DataReceived вызывается во вторичном потоке при получении данных от объекта SerialPort. Поскольку это событие вызывается на вторичномПоток, а не основной поток, пытаясь изменить некоторые элементы основного потока, такие как элементы пользовательского интерфейса, может вызвать исключение потока. Если необходимо изменить элементы в главной форме или элементе управления, отправьте запросы на изменение обратно с помощью Invoke,который будет выполнять работу в соответствующем потоке. "
Используйте Control.BeginInvoke для выполнения кода в основном потоке пользовательского интерфейса для отображения диалогового окна.например,
при условии, что этот код находится в классе, который наследуется от формы
var data = comport.ReadLine();
_buffer.Append(data);
if (_buffer.IsValid)
{
BeginInvoke((Action) (() =>
{
ReceiveMessagePopup popUp = new ReceiveMessagePopup(buffer);
popUp.Location = new Point(150, 150);
popUp.ShowDialog();
}));
}
Вы не хотите выполнять долго выполняющиеся задачи в событии, и, как указывает Давиде, показывает диалоговое окно.каждый раз, когда событие вызывается, вероятно, не очень хорошая идея, так как вы можете получить много событий, даже для одной строки данных из последовательного порта, поэтому я бы добавил данные, считанные из порта, в буфер, иесли буфер действителен (например, содержит целую строку / сообщение / пакет / что угодно), то покажите диалоговое окно