Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.51 MB
Время: 0.044 c
1-1125355391
Doctor Deejay
2005-08-30 02:43
2005.09.25
Чем лучше сжать в gzip или zip


14-1125339597
Константинов
2005-08-29 22:19
2005.09.25
Жизнь прекрасна, если Вы еще можете посмеяться над собой.


2-1123970686
ArtemESC
2005-08-14 02:04
2005.09.25
CopyFrom класса TStream


14-1124950374
dr Tr0jan
2005-08-25 10:12
2005.09.25
Форум по FreeBSD


3-1123674484
yk
2005-08-10 15:48
2005.09.25
как сортировать ?