• Как продвинуть сайт на первые места?
    Вы создали или только планируете создать свой сайт, но не знаете, как продвигать? Продвижение сайта – это не просто процесс, а целый комплекс мероприятий, направленных на увеличение его посещаемости и повышение его позиций в поисковых системах.
    Ускорение продвижения
    Если вам трудно попасть на первые места в поиске самостоятельно, попробуйте технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Если ни один запрос у вас не продвинется в Топ10 за месяц, то в SeoHammer за бустер вернут деньги.
  • Сервис онлайн-записи на собственном Telegram-боте
    Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое расписание, но и напоминать клиентам о визитах тоже. Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.
    Для новых пользователей первый месяц бесплатно.
    Чат-бот для мастеров и специалистов, который упрощает ведение записей:
    Сам записывает клиентов и напоминает им о визите;
    Персонализирует скидки, чаевые, кэшбэк и предоплаты;
    Увеличивает доходимость и помогает больше зарабатывать;


Иллюстрированный самоучитель по Delphi 7 для профессионалов

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

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

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

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

Когда, по мнению программиста, ввод/вывод должен быть завершен, можно проверить это, использовав функцию WaitForSingleObject.

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

Объект ожидания (параметр hHandle) в этом случае – тот самый, который создан нами, указан в структуре TOverlapped и передан в качестве параметра в функцию ReadFile или WriteFile. Можно указать любое время ожидания, в том числе бесконечное (параметр 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: = ReadFiie(FHandle, Buffer, Count, nb, SOverlapRd);
//
// Здесь можно вставить любые операторы, которые
// могут быть выполнены до окончания ввода/вывода
//
if not succ then
begin
LastError: = GetLastError;
if LastError = ERROR_IO_PENDING
then
begin
if WaitForSingleObject(OverlapRd.hEvent, INFINITE)=WAIT_OBJECT_0 then
GetOverlappedResult(FHandle, OverlapRd, nb, TRUE);
end
else
raise EAbort.Create(Format('Read failed, error %d',[LastError]));
end;
Result: = nb;
CloseHandle(hEvent);
end;

Если вы задали конечный интервал в миллисекундах, а операция еще не закончена, waitForSingieObject вернет код завершения WAIT_TIMEOUT. Функция GetOverlappedResult возвращает в параметре nb число байтов, действительно прочитанных или записанных во время отложенной операции.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.