Последовательный порт - я не могу вызвать форму и сделать ShowDialog в методе port_received? - PullRequest
1 голос
/ 16 сентября 2011

Я слушаю порт, и как только я получаю сообщение, выполняющее некоторую обработку, чем вставка в базу данных. Пока все хорошо. Проблема заключается в том, что в методе port_received я хотел бы открыть форму, показывающую, что устройство получило сообщение, и в зависимости от того, что пользователь нажал кнопку ОК и увидел сообщение. А на фоне всплывающей формы есть таймер и закрытие формы через 2 секунды, если пользователь не нажмет кнопку просмотра сообщения. Я звоню в форму, а не .ShowDialog(), после чего теряю связь через последовательный порт. Если я использую .Show(), я не могу видеть правильно часть кода:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    data = comport.ReadLine();

    ReceiveMessagePopup popUp = new ReceiveMessagePopup(data);
    popUp.Location = new Point(150, 150);
    popUp.ShowDialog();
    /// after that code I cannot do anything even cannot show any MessageBox. 
}

Ответы [ 2 ]

1 голос
/ 16 сентября 2011

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

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

см. Здесь примеры того, как использовать этот обработчик событий и сохранить входящие данные:

Как использовать событие dataReceived объекта порта SerialPort в C #?

0 голосов
/ 16 сентября 2011

Из статьи 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();
                                }));
}

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

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