Текущий архив: 2005.09.25;
Скачать: CL | DM;
Вниз
Неправильная работа потока Найти похожие ветки
← →
NeoMaster © (2005-07-25 11:31) [0]Создаю сервис. Сервис создан для слежения за изменением файловой системы. Саму процедуру обработки слежения помещаю в отдельный поток в методу Execute. Создаю поток
NCThread:=TNCThread.Create(False);
Всё хорошо компилится и запускается, но поток выполняется только один раз. Так как в файл записывается только один(самый первый) изменённый файл. Вот сокращённый код потока:...
i: integer;
...
i:=0;
...
Procedure TNCThread.execute;
var
hDir : THandle;
lpBuf : Pointer;
Ptr : Pointer;
cbReturn : Cardinal;
FileName : PWideChar;//Имя файла
iniFile: TIniFile;
begin
iniFile:=TiniFile.Create("1.ini")
hDir := CreateFile ("C:\",GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir = INVALID_HANDLE_VALUE
then begin ShowMessage(SysErrorMessage(GetLastError)); exit; end;
GetMem(lpBuf,BUF_SIZE);
Repeat
ZeroMemory(lpBuf,BUF_SIZE);
if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true, FILE_NOTIFY_CHANGE_FILE_NAME + FILE_NOTIFY_CHANGE_DIR_NAME + FILE_NOTIFY_CHANGE_LAST_WRITE + FILE_NOTIFY_CHANGE_ATTRIBUTES + FILE_NOTIFY_CHANGE_SIZE + FILE_NOTIFY_CHANGE_LAST_ACCESS + FILE_NOTIFY_CHANGE_CREATION + FILE_NOTIFY_CHANGE_SECURITY,@cbReturn,nil,nil) then Break;
Ptr:=lpBuf;
repeat
GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName, PFileNotifyInformation(Ptr).FileNameLength div 2+1);
i:=i+1;
iniFile.WriteString("MAIN"."NAME" + IntToStr(i), FileName);
FreeMem(FileName);
until false;
until false;
FreeMem(lpBuf);
End;
← →
Piter © (2005-07-25 11:47) [1]1) Ну например ты создаешь TIniFile:
iniFile:=TiniFile.Create("1.ini")
Но нигде его не закрываешь:iniFile.Free
2) потоки с бесконечными циклами... это нечто :)
А почему использовать repeat, а не:while true do ...
? :)
← →
Digitman © (2005-07-25 11:57) [2]
> Создаю поток NCThread:=TNCThread.Create(False)
в каком месте ?
← →
Kolan © (2005-07-25 12:01) [3]Чтобы процедура выполнялась в цикле надо делать так
ВExecute
:while not Terminated do
SomeWork();
А код вSomeWork
...
← →
NeoMaster © (2005-07-25 13:13) [4]Не помогает. Без разницы, что
Repeat...Until
, чтоWhile true do
, чтоwhile not Terminated do
. Всё равно ловит только первое ищменение. Поток создаю в процедуре ServiceStart. А бесконечный цикл - это для примера.
← →
Digitman © (2005-07-25 13:17) [5]
> Поток создаю в процедуре ServiceStart
какие еще события сервиса обрабатываешь ?
если создаешь поток в обычном (не сервисном) приложении, результаты те же ? если те же, какие ты принял меры по отладке приведенного кода в обычном приложении, прежде чем переносить его в сервис-приложение ?
← →
Piter © (2005-07-25 13:29) [6]NeoMaster © (25.07.05 13:13) [4]
мой текст:
Но нигде его не закрываешь:
iniFile.Free
ты значит проигнорировал. Молодец!
← →
ANB © (2005-07-25 14:06) [7]
> Ptr:=lpBuf;
> repeat
> GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
> ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
> lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName,
> PFileNotifyInformation(Ptr).FileNameLength div 2+1);
> i:=i+1;
> iniFile.WriteString("MAIN"."NAME" + IntToStr(i), FileName);
> FreeMem(FileName);
> until false;
- вот сей кусок меня тоже определенно смущает. Про Free уже писали. А здесь я не вижу в упор условия для выхода из цикла. Да, и для выбора следующего файла из списка тоже. Может не внимательно смотрел.
← →
Slym © (2005-07-26 05:27) [8]Вообще код ужасный... С такими возможными утечками памяти и абсолютной необработкой искл. ситуаций сервисы писать нельзя.
← →
Slym © (2005-07-26 05:49) [9]ПРЕДУПРЕЖДЕНИЕ: Код не проверял на работоспособность.
const BUF_SIZE=4096;
var
i:integer;
IniFile: TIniFile;
hDir:THandle;
lpBuf : Pointer;
FNI : PFileNotifyInformation;
cbReturn : Cardinal;
FileName : WideString;//Имя файла
begin
i:=0;
IniFile:=TiniFile.Create("1.ini");
try
hDir:=CreateFile ("C:\",GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir = INVALID_HANDLE_VALUE then
RaiseLastOSError;
try
GetMem(lpBuf,BUF_SIZE);
try
while not Terminated do
begin
ZeroMemory(lpBuf,BUF_SIZE);
if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true, FILE_NOTIFY_CHANGE_FILE_NAME + FILE_NOTIFY_CHANGE_DIR_NAME + FILE_NOTIFY_CHANGE_LAST_WRITE + FILE_NOTIFY_CHANGE_ATTRIBUTES + FILE_NOTIFY_CHANGE_SIZE + FILE_NOTIFY_CHANGE_LAST_ACCESS + FILE_NOTIFY_CHANGE_CREATION + FILE_NOTIFY_CHANGE_SECURITY,@cbReturn,nil,nil) then
RaiseLastOSError;
if cbReturn=0 then continue;
FNI:=lpBuf;
repeat
SetString(FileName,FNI.FileName,FNI.FileNameLength);
IniFile.WriteString("MAIN","NAME"+IntToStr(i), FileName);
Inc(i);
Inc(FNI,FNI.NextEntryOffset);
until FNI.NextEntryOffset<>0;
end;
finally
FreeMem(lpBuf,BUF_SIZE);
end;
finally
CloseHandle(hDir);
end;
finally
IniFile.Free;
end;
end;
← →
NeoMaster © (2005-07-26 12:56) [10]В проекте я не вывожу результаты сразу в ini файл, а здесь для примера использовал эту возможность. Но для Piter специально допишу:)
...
iniFile.Free;
...
Толку всё равно нет. Сначала сделаю этот сервис работоспособным, а потом уже будет оптимизация.
Для Slym:
Это мой первый проект-сервис. Соответствующей литературы не нашёл. Вот и приходится методом проб и ошибок. Кстати этот код очень стабильно и ровно работает в обычном exe приложение(сейчас мне и необходимо перегнать приложение в сервис). Посмотрел твой код. Хоть что начало работать, но реальных изменений сервис так и не находит, а выводит сообщение только об одном и том же изменившемся файле. Изменяешь кокой-либо файл, а сервис выводит, что изменился совершенно другой файл. Но всё равно я ещё поколдую.
← →
Digitman © (2005-07-26 15:34) [11]
> приходится методом проб и ошибок
в станд.справке есть инф-ция по отладке сервисов, написанных в делфи, средствами встр.отладчика Делфи
← →
Digitman © (2005-07-26 15:47) [12]
> Кстати этот код очень стабильно и ровно работает в обычном
> exe приложение
врешь.
галиматьи и несуразностей в этом коде - хоть отбавляй.
← →
tesseract © (2005-07-27 20:59) [13]>> GetMem(lpBuf,BUF_SIZE); , FreeMem(lpBuf,BUF_SIZE); - несуразность BUF_SIZE DELPHI проигнорирует NEW и DISPOSE с какого-то перепоя в D7 вызывают меньше проблем.
Слишком много try except.
После сбоя CreteFile Вызов CloseHandle вызовет ошибку Delphi - отключается в настройках дебаггера.
@cbReturn - точно а может лучше без собачки (Не уверен но подозреваю)
← →
Slym © (2005-07-28 05:27) [14]tesseract © (27.07.05 20:59) [13]
Слишком много try except не бывает... Особенно в постоянно и интенсивно работающем приложении (сервисе)...
Если начнет кушать память, Handl"ы, прочие системные объекты- сервер долго не протянет
← →
tesseract © (2005-07-29 10:02) [15]>>> Если начнет кушать память, Handl"ы, прочие системные объекты- сервер долго не протянет.
Не кушай память и прочие системные объекты Try.. except служит для того чтобы обработать ошибку, а не избавится от них.
← →
NeoMaster © (2005-07-29 11:12) [16]Вообще-то там структуры try..finally. Но всё равно спасибо всем - ошибку свою я понял. Всё работает(тьфу,тьфу,тьфу через левое плечо). Сейчас код оптимизировать пойду.
Страницы: 1 вся ветка
Текущий архив: 2005.09.25;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.039 c