Я создал класс, который обрабатывает последовательный порт асинхронно. Я использую его для связи с модемом. Я понятия не имею, почему, но иногда, когда я закрываю свое приложение, я получаю синий экран, и мой компьютер перезагружается. Я регистрировал свой код шаг за шагом, но когда появился BSOD и мой компьютер перезагрузился, файл, в который я записывал данные, содержал только пробелы. Поэтому я понятия не имею, в чем может быть причина BSOD.
Я внимательно просмотрел свой код и обнаружил несколько возможных причин проблемы (я искал все, что могло бы привести к доступу к нераспределенной памяти и возникновению исключений AV).
Когда я переосмыслил идею асинхронных операций, мне пришло в голову несколько вещей. Пожалуйста, убедитесь, что это правильно:
1) WaitCommEvent () получает указатель на перекрывающуюся структуру. Поэтому, если я вызываю WaitCommEvent () внутри функции и затем покидаю функцию, перекрывающаяся структура не может быть локальной переменной, верно? Переменная маски события и дескриптор события тоже, верно?
2) ReadFile () и WriteFile () также принимают ссылки или указатели на переменные. Поэтому все эти переменные должны быть доступны до тех пор, пока не завершатся перекрывающиеся операции чтения или записи, верно?
3) Я вызываю WaitCommEvent () только один раз и проверяю его результат в цикле, а пока делаю другие вещи. Поскольку я понятия не имею, как завершить асинхронные операции (возможно ли это?), Когда я уничтожаю свой класс, который хранит дескриптор последовательного порта, я сначала закрываю дескриптор, а затем жду события в использованной перекрытой структуре при вызове функции WaitCommEvent (). Я делаю это, чтобы быть уверенным, что поток, который асинхронно ожидает события comm, не имеет доступа к полям моего класса, который уничтожен. Это хорошая идея или глупая?
try
CloseHandle(FSerialPortHandle);
if Assigned(FWaitCommEvent) then
FWaitCommEvent.WaitFor(INFINITE);
finally
FSerialPortHandle := INVALID_HANDLE_VALUE;
FreeAndNil(FWaitCommEvent);
end;
Прежде, чем я заметил все это, большинство переменных, упомянутых в первом и втором пунктах, были локальными переменными функций, которые вызвали три метода выше. Может ли это быть причиной BSOD или я должен искать другие ошибки в моем коде?
Когда я исправил код, BSOD прекратил свое существование, но это может быть совпадением. Как вы думаете?
Будут оценены любые идеи. Заранее спасибо.
Я прочитал документацию по функции CancelIo (), и в ней говорится, что этот метод отменяет все операции ввода-вывода, выполненные вызывающим потоком. Можно ли ждать FWaitCommEvent после вызова CancelIo (), если я знаю, что WaitCommEvent () был выпущен не тем потоком, который вызывает CancelIo ()?
if Assigned(FWaitCommEvent) and CancelIo(FSerialPortHandle) then
begin
FWaitCommEvent.WaitFor(INFINITE);
FreeAndNil(FWaitCommEvent);
end;
Я проверил, что происходит в таком случае, и поток, вызывающий этот фрагмент кода, не заблокировался, даже если он не вызывал WaitCommEvent (). Я проверил на Windows 7 (если это имеет значение). Могу ли я оставить код как есть или это опасно? Может быть, я неправильно понял документацию, и это причина моего вопроса. Я прошу прощения за то, что задал так много вопросов, но я действительно должен быть уверен в этом.
Спасибо.