В последнее время я делаю серийные коммуникации, поэтому я подготовил класс, являющийся простым интерфейсом ко всем функциям Windows API, ответственным за чтение, запись и т. Д. Все операции ввода/вывода внутри этого класса обрабатываются асинхронно.Последовательный порт и ошибки обработки во время операций перекрытия ввода-вывода
Прежде чем перейти к моему вопросу, позвольте мне показать вам, как я пишу и читаю данные из последовательного порта (это только функция чтения, потому что структура записи одна точно такая же, поэтому нет смысла показывать оба из них).
function TSerialPort.Read(var pBuffer; const lBufferSize: Cardinal): Cardinal;
var
lOverlapped: OVERLAPPED;
lLastError: Cardinal;
lEvent: TEvent;
begin
lEvent := TEvent.Create(nil, True, False, '');
try
FillChar(lOverlapped, SizeOf(lOverlapped), 0);
lOverlapped.hEvent := lEvent.Handle;
if not ReadFile(FSerialPortHandle, pBuffer, lBufferSize, Result, @lOverlapped) then
begin
lLastError := GetLastError;
if (lLastError <> ERROR_IO_PENDING) and (lLastError <> ERROR_SUCCESS) then
raise Exception.Create(SysErrorMessage(lLastError));
case lEvent.WaitFor(INFINITE) of
wrSignaled:
if not GetOverlappedResult(FSerialPortHandle, lOverlapped, Result, False) then
raise Exception.Create(SysErrorMessage(GetLastError));
wrError:
begin
lLastError := lEvent.LastError;
//this is a call to Windows.CancelIo(FSerialPortHandle);
if Self.CancelIO() then
lEvent.WaitFor(INFINITE);
raise Exception.Create(SysErrorMessage(lLastError));
end;
end;
end;
finally
FreeAndNil(lEvent);
end;
end;
Прежде чем спросить меня, почему я открыть последовательный порт для перекрывающихся операций в то время как эта функция ожидает операция чтения до конца, вот мое объяснение - только при открытии последовательного порта таким образом можно указать время WaitCommEvent (метод) ждет событий. Если я открою порт для операций без перекрытия, WaitCommEvent() будет блокироваться до тех пор, пока на последовательном порту не появится событие, которое не всегда может привести к тому, что вызывающий поток блокируется навсегда.
Тем не менее, давайте сосредоточимся на вышеуказанной функции Read().
1) Прежде всего, я жду без ограничения срока для события. Есть ли вероятность, что текущий поток будет блокироваться навсегда по какой-то причине из-за этого? Я не знаю, могу ли я быть на 100% уверен, что событие рано или поздно будет установлено потоком, выполняющим операцию чтения асинхронно. Я знаю, что когда тайм-ауты чтения последовательного порта установлены на ноль, операция чтения не будет завершена до тех пор, пока не будет прочитано заданное количество байтов, но это поведение, о котором я знаю. Мой вопрос касается неожиданных ситуаций, которые могут привести к тому, что событие никогда не будет установлено, и метод WaitFor() будет ждать вечно - возможно, это произойдет?
2) WaitFor() может возвращать wrError, который сообщает, что во время операции ожидания произошла некоторая ошибка (но это не связано с перекрытой операцией чтения вообще?). Поэтому я думаю, что я больше не должен ждать завершения операции чтения, потому что дескриптор события больше не может быть использован, не так ли? Таким образом, я вызываю метод CancelIO(), чтобы отменить операцию чтения, дождавшись, когда событие будет установлено потоком, асинхронно выполнив отмененное чтение, и только затем вызовет исключение. Я ожидаю, что чтение будет отменено этим потоком, потому что, если я немедленно покинул свой метод Read() (без отмены ввода-вывода), я бы заставлял этот поток записывать свои данные (перекрывающиеся данные записи) в локальные переменные, которые быть более недействительным тогда, правильно? С другой стороны, существует ли опасность, что текущий поток будет заблокирован навсегда из-за вызова WaitFor (INFINITE) перед сбором исключения?
Буду признателен, если вы сообщите мне, если вышеуказанные утверждения верны или нет, и прокомментируйте их, пожалуйста.
спасибо, что заранее.
Спасибо за ваше предложение.Возможно, вы правы, но я все равно хотел бы узнать ответ на мои вопросы. Это мое любопытство или, скорее, желание расширить мои знания по этой теме. –