![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Overlapped IO [D5, Win2k]
Rad © (2003-12-23 03:07:00)
Пытаюсь асинхронно писать сообщения в текстовый лог:
var
s: string;
procedure WriteLogFile(hFile: THandle; var ovl: OVERLAPPED; sLogLn: string);
var
i: cardinal;
begin
s:= sLogLn + #13#10;
ovl.Offset:= GetFileSize(hFile, @ovl.OffsetHigh);
WriteFile(hFile, s, Length(s), i, @ovl);
SetFilePointer(hFile, ovl.InternalHigh, nil, FILE_CURRENT);
end;
hFileоткрыт сFILE_FLAG_OVERLAPPED, результат записи не интересует, поэтомуovl.hEvent:= 0;
В файле оказывается чушь.
Если сделать примерно так:
WriteFileEx(hFile, s, Length(s), ovl, nil);- то весь валится весь процесс (в упрощенном тестовом примере всё работает как раз сWriteFileEx, а чушь пишется сWriteFile); но при nil-указателе на Callback-функцию (FileIOCompletionRoutine) это некоторым образом логично :)
Если короче, то я запутался с этим асинхронным выводом :)
Никто не может кинуть ссылкой, где можно почитать какой-никакой примерчик на эту тему (но не про работу с COM-портами)?
y-soft (2003-12-23 16:54:00) [1]
>Rad © (23.12.03 15:52) [5]
Вот ждать-то как раз и не хотелось бы: типа, отправил запрос на запись и забыл, записалось или нет - не столь важно.
Но тогда как быть уверенным, что указатель перемещается правильно?
Перекрытый ввод/вывод обычно используют только в приложениях, где больше одного потока и одновременно производится запись/чтение в несколько файловых объектов (или в один одновременно), иначе выгоды от него никакой, т.к. все равно приходится ждать завершения операции, разве что не потребляет процессорное время в момент ожидания :)
Вот и делают так, что один поток осуществляет взаимодействие с пользователем и контролирует второй поток, а второй - непосредственно дает команды на ввод/вывод в файловые объекты и ждет их завершения обычно с помощью WaitForMultipleObjects. В этом случае получается очень экономно и надежно, т.к. не нужно использовать объекты синхронизации внутри второго потока для разделения доступа к файлам...
Rad (2003-12-23 15:52:00) [2]
y-soft © (23.12.03 15:12) [4]
прям вот на Вы... :)
> уверены, что в момент вызова SetFilePointer поле ovl.InternalHigh показывает верное значение?
мда, не уверен.
а если
SetFilePointer(hFile, Length(s), nil, FILE_CURRENT)?
> использовать WaitXXX или GetOverlappedResult с установленным флагом ожидания до вызова SetFilePointer, иначе перекрытый ввод теряет смысл
Вот ждать-то как раз и не хотелось бы: типа, отправил запрос на запись и забыл, записалось или нет - не столь важно.
y-soft (2003-12-23 15:12:00) [3]
>Rad © (23.12.03 03:07)
А Вы уверены, что в момент вызова SetFilePointer поле ovl.InternalHigh показывает верное значение? Все-таки не мешало бы ожидать окончания записи, иногда ведь WriteFile завершется с ошибкой 997 ERROR_IO_COMPLETE и в InternalHigh в этом случае количество записанных байт не заносится до фактического окончания записи. Не мешало бы для гарантии использовать WaitXXX или GetOverlappedResult с установленным флагом ожидания до вызова SetFilePointer, иначе перекрытый ввод теряет смысл...
Polevi (2003-12-23 09:21:00) [4]
PChar(s)^
Rad (2003-12-23 04:28:00) [5]
SPeller © (23.12.03 04:00) [1]
Спасибо!!!
Хм... А как этот приём понимать? :)
SPeller (2003-12-23 04:00:00) [6]
передавай в функцию WriteFile s[1] вместо s.