hCom := CreateFile ('COM2', GENERIC_READ or G1ETTERIC_WRIT/E,

0, NTL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0) ;
if hCom = INVALID J1ANDLE_VALUE then begin
raise EAbort.CreateFmt ('Ошибка открытия порта: %d', [GetLastError]) ;
end;

Самое большое отличие от предьщущего примера - в скромном флаге FILE FLAG OVERLAPPED. О роли этих изменений - в следующем разделе.

Отложенный (асинхронный) ввод/вывод

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

(threads) операционной системы, который и осуществляет фактические обязанности по работе с устройством. Время доступа всех периферийных устройств гораздо больше доступа к ОЗУ, и ваша программа, вызвавшая Read или Write, будет дожидаться окончания операции ввода/вывода. Замедление работы программы налицо.

Выход был найден в использовании отложенного (overlapped) ввода/вывода. До начата отложенного ввода/вывода инициализируется дескриптор объекта типа события (функция createEvent) и структура типа TOveriapped. Вы вызываете функцию ReadFile или WriteFile, в которой последним параметром указываете на TOveriapped. Эта структура содержит дескриптор события Windows (event).

ОС начинает операцию (ее выполняет отдельный программный поток, скрытый от программиста) и немедленно возвращает управление; вы можете не тратить время на ожидание. Признак того, что операция началась и продолжается - получение кода возврата ERRORJO PENDING. Пусть вас не пугает слово "error" в названии - это совершенно нормально. Если операция продолжается долго (а чтение и запись файлов на дискете, да и на диске, именованных каналов можно отнести к "длинным" операциям), то программа может спокойно выполнять последующие операторы. Событие будет "взведено" ОС тогда, когда ввод/вывод закончится.

Когда, по мнению программиста, ввод/вывод должен быть завершен, можно проверить ЭТО, ИСПОЛЬЗОВав функциюWaitForSingleObject.

function WaitForSingleObject (hHandle: THandle;
dwMilliseconds: DWORD) : DWORD;

Объект ожидания (параметр hHandle) в этом случае - тот самый, который создан нами, указан в структуре TOveriapped и передан в качестве параметра в функцию ReadFile или WriteFiie. Можно указать любое время ожидания, в том числе бесконечное (параметр Timeout при этом равен константе INFINITE). Признаком нормального завершения служит получение кода возврата WAIT_OBJECT_0.

|!листинг9.2, Пример отложенной операций чтения ": ' ' :о\'^'"
'"! о'^*'Ü
function TMyClass.Read(var Buffer;
Count: Longint) : Longint;
var succ : boolean;nb : Cardinal;LastError : Longint;
Overlap: TOveriapped;
begin
FillChar(Overlap,SizeOf(Overlap),0);
Overlap.hEvent := CreateEvent(nil, True, False, nil);
Result := Maxlnt;
succ := ReadFile(FHandle, Buffer, Count, nb, SOverlapRd);

II

// Здесь можно вставить любые операторы, которые // могут быть выполнены до окончания ввода/вывода //

if not suce then begin


⇐ Предыдущая страница| |Следующая страница ⇒

Программирование в Delphi 7



Новости за месяц

  • Август
    2017
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс