Какова цель буфера записи SerialPort? - PullRequest
3 голосов
/ 20 апреля 2011

Снаружи объекта SerialPort, кажется, не имеет значения, какой размер буфера записи и заполнен он или нет.

При использовании синхронной записи метод записи блокируется, пока все данные не будут иметьбыл отправлен, а буфер пуст.

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

Поведение объекта serialport, по-видимому, одинаково, независимо от того, сколько данных находится в буфере и является ли илине буфер заполнен.Похоже, что при заполнении буфера записи ошибок не происходит.

Итак, зачем вообще проверять BytesToWrite и WriteBufferSize?Есть ли способ, которым SerialPort ведет себя по-другому, когда буфер записи заполнен?

Ответы [ 3 ]

1 голос
/ 20 апреля 2011

Свойство C # SerialPort.BytesToWrite соответствует неуправляемому полю Win32 COMSTAT.cbOutQue, которое описывается как:

  • Число байтов пользовательских данных, остающихся для передачи для всех операций записи.Это значение будет нулевым для неперекрытой записи.

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

1 голос
/ 20 апреля 2011

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

Что касается того, почему вы хотите проверить BytesToWrite - вам часто интересно знать, были ли отправлены все ваши данные, прежде чем переходить к следующему, что вы хотите сделать, вы можете ожидать ответа после определенного периода времени. время, вы, возможно, захотите узнать, какова фактическая скорость передачи и т. д.

0 голосов
/ 10 августа 2011

Я хотел создать тестовую утилиту, которая постоянно отправляет 0xAA через последовательный порт, без пробелов, навсегда. Меня не волнует RX.

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

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

Обратите внимание, что вы можете обойтись без BeginWrite без EndWrite в течение короткого времени, но в итоге у вас закончатся ресурсы. Я в основном просто вставляю фиктивный EndWrite.

    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        timerFill.Enabled = checkBox2.Checked;
    }

    private void timerFill_Tick(object sender, EventArgs e)
    {
        GenerateSquareWave();
    }

    int const bufferSize = 256;

    void GenerateSquareWave()
    {
        int k = serialPort1.BytesToWrite;
        label11.Text = k.ToString();
        if (k < bufferSize)
        {
            byte[] data = new byte[bufferSize];
            for (int i = 0; i < bufferSize; i++)
            {
                data[i] = 0xAA;
            }
            serialPort1.BaseStream.BeginWrite(data, 0, data.Length, new AsyncCallback((IAsyncResult ar) => serialPort1.BaseStream.EndWrite(ar)), null);
        }
    }
...