Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Асинхронный I/O


Darkwing ©   (2005-06-25 15:06:00) 

Имею вот такую функцию. Она должна читать из файла данные, при этом время ограничено (TimeOut: word). Но она никогда не выдает, то что время закончилось, даже когда таймаут 10 мс а читать надо 100 МБ (например). В чем ошибка, скажите пожалуйста?

function Read(var Buffer; Count: DWORD; TimeOut: word; H: THandle): word;
var RealBytes: DWORD;
   Ovlp: TOverlapped;
begin
Ovlp.hEvent := CreateEvent(nil, true, false, nil);
resetEvent(Ovlp.hEvent);
ReadFile(H, Buffer, Count, RealBytes, @Ovlp);
if WaitForSingleObject(Ovlp.hEvent, TimeOut) = WAIT_OBJECT_0
 then if RealBytes <> Count then Result := 1 else Result := 2
 else Result := 0;
CloseHandle(Ovlp.hEvent);
end;


Darkwing   (2005-06-25 22:16:00) [1]

вот ксати про флажок то я не очень уверен, что включил.
Действительно сделаю лучше отдельным потоком да и все.

Спасибо тебе, добрый Reindeer Moss Eater, что уделил внимание!


Reindeer Moss Eater   (2005-06-25 22:11:00) [2]

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

А так, вообще, вместо всей этой дури, которая здесь совершенно ни к месту, надо делать обычное поблочное чтение во вторичном потоке.


Darkwing   (2005-06-25 21:55:00) [3]

В хелпе просто написано, что мол приложние дальше себе работает, а Overlaped как раз и запускает для данного i/o свой поток. Если не так то напишите пожалста.

И RealBytes <> Count - это вообще можно опустить, главно, что она всегда дает WAIT_OBJECT_0.

Это оно пока в главном потоке я только эту технологию прощупываю. не выходит вот.


Reindeer Moss Eater   (2005-06-25 21:45:00) [4]

При этом все приложение тормозило 1 сек.

И правильно делало. Так и надо поступать с теми, кто вызывает функции ожидания/синхронизации в основном потоке GUI приложения.


Reindeer Moss Eater   (2005-06-25 21:43:00) [5]

Во первых, при асинхронном чтении бессмысленно проверять
if RealBytes <> Count

Во вторых, асинхронные операции с дисковыми файлами поддерживаются только на NT и выше.

Ну и в третьих.
Вторичный поток - это все что требуется для решения задачи.


Darkwing   (2005-06-25 21:38:00) [6]

Задал читать 100 МБ и таймаут 10 мс. При этом все приложение тормозило 1 сек. По идее не должно выдать WAIT_OBJECT_0.


Reindeer Moss Eater   (2005-06-25 21:34:00) [7]

Мне не надо пояснять зачем это надо.

Главно сначала определить, что за отведенное время данные не были прочитаны.
С чего ты решил, что они не былипрочитаны?


Darkwing   (2005-06-25 21:30:00) [8]

Поясняю для чего, например, это надо:

1) Юзер совершает действие требующее чтения данных из файла
2) Программа пытается прочитать эти данные, а в случае если это долгий процесс (дискета, большой блок данных, сетка 10 мб/с) она должна вывести об этом мессадж чтобы юзер не волновался.

и дело как раз в том, что эта процедура, каким бы ни был долгим процесс всегда возвращает значение WAIT_OBJECT_0, как будто он завершился менее чем за Timeout.


Reindeer Moss Eater   (2005-06-25 18:20:00) [9]

Главно сначала определить, что за отведенное время данные не были прочитаны.

С чего ты решил, что они не были прочитаны?


Darkwing   (2005-06-25 17:57:00) [10]

Дело в том, что я потом буду разбираться отчего не произошло чтение. Главно сначала определить, что за отведенное время данные не были прочитаны. То есть если сработает Event за определенное время.


Reindeer Moss Eater   (2005-06-25 15:24:00) [11]

Но она никогда не выдает, то что время закончилось,

if WaitForSingleObject(Ovlp.hEvent, TimeOut) = WAIT_OBJECT_0
then if RealBytes <> Count then Result := 1 else Result := 2
else Result := 0;

А как ты по такому своему коду надеешься понять, что наступил таймаут?
То есть, все, что не WAIT_OBJECT_0 это обязательно по твоему таймаут?


Reindeer Moss Eater   (2005-06-25 15:20:00) [12]

If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult.


Наверх

Титульная страница Поиск, карта сайта Написать письмо