Событие .NET SerialPort DataReceived не запускается - PullRequest
6 голосов
/ 17 февраля 2010

У меня есть тестовое приложение WPF для оценки основанного на событиях обмена данными через последовательный порт (вместо опроса последовательного порта). Проблема в том, что событие DataReceived, похоже, вообще не запускается.

У меня есть очень простая форма WPF с TextBox для ввода данных пользователем, TextBlock для вывода и кнопкой для записи ввода в последовательный порт.

Вот код:

public partial class Window1 : Window
{
    SerialPort port;

    public Window1()
    {
        InitializeComponent();

        port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
        port.DataReceived +=
            new SerialDataReceivedEventHandler(port_DataReceived);  
        port.Open();
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Debug.Print("receiving!");
        string data = port.ReadExisting();
        Debug.Print(data);
        outputText.Text = data;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Debug.Print("sending: " + inputText.Text);
        port.WriteLine(inputText.Text);
    }
}

Теперь вот осложняющие факторы:

  1. Ноутбук, на котором я работаю, не имеет последовательных портов, поэтому для настройки COM2 я использую программу под названием «Эмулятор виртуального последовательного порта». VSPE работал превосходно в прошлом, и не ясно, почему он будет работать только с классом .NET SerialPort, но я упомяну это на всякий случай.

  2. Когда я нажимаю кнопку в форме, чтобы отправить данные, мое окно гипертерминала (подключенное к COM2) показывает, что данные проходят. Да, я отключаю Гипертерминал, когда хочу проверить способность моей формы читать порт.

  3. Я пытался открыть порт перед подключением события. Без изменений.

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

EDIT:

Вот консольная версия (изменена с http://mark.michaelis.net/Blog/TheBasicsOfSystemIOPortsSerialPort.aspx):

class Program
{
    static SerialPort port;

    static void Main(string[] args)
    {
        port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
        port.DataReceived +=
            new SerialDataReceivedEventHandler(port_DataReceived);
        port.Open();

        string text;
        do
        {
            text = Console.ReadLine();
            port.Write(text + "\r\n");
        }
        while (text.ToLower() != "q");
    }

    public static void port_DataReceived(object sender,
        SerialDataReceivedEventArgs args)
    {
        string text = port.ReadExisting();
        Console.WriteLine("received: " + text);
    }
}

Это должно устранить любые опасения, что это проблема Threading (я думаю). Это тоже не работает. И снова Hyperterminal сообщает о данных, отправленных через порт, но консольное приложение, похоже, не запускает событие DataReceived.

РЕДАКТИРОВАНИЕ № 2:

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

Если я наберу в консольном приложении событие Событие DataReceived приложения WPF, с ожидаемой ошибкой потоков (с которой я знаю, как бороться).

Если я ввожу в приложение WPF, запускается событие DataReceived консольного приложения, и оно отображает данные.

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

Ответы [ 8 ]

13 голосов
/ 07 октября 2013
port.DtrEnable = true;

Это решило это для меня, флаг DataTransmitReady не был включен, поэтому данные не были получены.

3 голосов
/ 17 февраля 2010

Не могу сказать точно, но может быть проблема с многопоточностью. WPF по-разному обрабатывает потоки, и я полагаю, что опрос виртуального порта выполняется асинхронно. Вы пробовали это с Windows Forms или консольным приложением, чтобы доказать, что оно может работать вообще?

2 голосов
/ 17 февраля 2010

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

Вот почему мое первоначальное объявление выглядит так:

comControl = new SerialPort();

//This is important - determine your min nb of bytes at which you will fire your event, mine is 9
comControl.ReceivedBytesThreshold = 9; 

//register the event handlers
comControl.DataReceived += new SerialDataReceivedEventHandler(OnReceive);
comControl.PinChanged += new SerialPinChangedEventHandler(OnPinChanged);

Я разделил методы открытия и закрытия портов, так как часто проверяю, закрыт ли com-порт.

public bool OpenPort()
{
    try
    {
        //must keep it open to maintain connection (CTS)
        if (!comControl.IsOpen)
        {
             comControl.Open();
             comControl.RtsEnable = true;
        }
    }
    catch (Exception e)
    {
        //error handling here
    }
}

Наконец, убедитесь, что ваш драйвер Virtual Com Port установлен правильно и что вы используете правильный порт, подключи и играй для моего адаптера было недостаточно. Если вы хотите создать своего рода элемент управления, который позволит вам выбирать порты, доступные во время выполнения, следующая команда выдаст вам доступные порты:

System.IO.Ports.SerialPort.GetPortNames()
0 голосов
/ 03 декабря 2015

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

Моим решением было удалить McAfee антивирус и все, что с этим связано. Когда я увидел журналы McAfee, в нем были записи об остановке потоков, и я предположил, что SerialDataReceivedEventHandler() выполняется в потоке.

Я надеюсь, что это решение работает для вас. С уважением.

0 голосов
/ 24 июля 2013

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

В .NET 4.0 обработчик событий запускается в потоке ThreadPool, и при определенных обстоятельствах может произойти существенная задержка, прежде чем это произойдет. (В моем коде, который отлично работал в .NET 2.0, проблемы наблюдались, как только мы обновили до .NET 4.5. Обработчик событий часто запускался гораздо позже, чем ожидалось, а иногда он не срабатывал все!)

Вызов ThreadPool.SetMinThreads(...) с большим значением для потоков завершения заставил проблему исчезнуть так же быстро, как и появилась. В контексте нашего приложения ThreadPool.SetMinThreads(2, 4) было достаточно. На машинах, где наблюдалась проблема, значения по умолчанию (полученные путем вызова ThreadPool.SetMinThreads) были равны 2.

0 голосов
/ 27 апреля 2013

Я тоже пользуюсь VSPE! Это работает чудесно ... У меня была такая же проблема, и способ, которым я ее исправил, состоял в том, чтобы сделать два com-порта парой в VSPE вместо того, чтобы просто создать два виртуальных com-порта

0 голосов
/ 02 марта 2013

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

0 голосов
/ 11 марта 2010

Могу только предположить, что проблема действительно была в программе Virtual Serial Port Emulator. Нельзя сказать, что есть проблема с этим программным обеспечением: VSPE до сих пор работал очень хорошо для меня. Но между моим кодом и тем, как я настроил разъем VSPE, был какой-то конфликт.

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