Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.21;
Скачать: CL | DM;

Вниз

Асинхронный I/O   Найти похожие ветки 

 
Darkwing ©   (2005-06-25 15:06) [0]

Имею вот такую функцию. Она должна читать из файла данные, при этом время ограничено (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;


 
Reindeer Moss Eater ©   (2005-06-25 15:20) [1]

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.


 
Reindeer Moss Eater ©   (2005-06-25 15:24) [2]

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

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

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


 
Darkwing ©   (2005-06-25 17:57) [3]

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


 
Reindeer Moss Eater ©   (2005-06-25 18:20) [4]

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

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


 
Darkwing ©   (2005-06-25 21:30) [5]

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

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

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


 
Reindeer Moss Eater ©   (2005-06-25 21:34) [6]

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

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


 
Darkwing ©   (2005-06-25 21:38) [7]

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


 
Reindeer Moss Eater ©   (2005-06-25 21:43) [8]

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

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

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


 
Reindeer Moss Eater ©   (2005-06-25 21:45) [9]

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

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


 
Darkwing ©   (2005-06-25 21:55) [10]

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

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

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


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

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

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


 
Darkwing ©   (2005-06-25 22:16) [12]

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

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



Страницы: 1 вся ветка

Текущий архив: 2005.08.21;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.052 c
1-1122142486
ivanick
2005-07-23 22:14
2005.08.21
Кириллица в Delphi


3-1121166715
Максим
2005-07-12 15:11
2005.08.21
Работа с полями DBGrid ?


1-1122702360
Viktop
2005-07-30 09:46
2005.08.21
Доступ к истории WebBrowser


1-1123060934
TDionis
2005-08-03 13:22
2005.08.21
Несовместимость String и Char


4-1119958510
Pearled
2005-06-28 15:35
2005.08.21
Установка разрешений доступа к какталогу