![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Асинхронный 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.