Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос по потокам [XP]


Страницы:   1 2

petvv ©   (2009-03-17 07:52:00) 

Вот есть код:

constructor TMonDirThread.Create(aPath: String);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FPath := aPath;
 Self.Priority := tpHighest;
 Resume;
end;

procedure TMonDirThread.UpdateLog;
var
 s: string;
 f: TextFile;
 i: Integer;

begin
   Result:=1;
   KolStr:=0;
   Full:= WideCharToString(Path)+'\'+WideCharToString(FileName);
   CreateDBF();
   AssignFile(f, Full);
   Reset(f);
   while not EOF(f) do
     begin
       ReadLn(f, s);
       if Result=2 then
         begin
         // Сдесь получаем № и дату накладной
           GetNom(s,12,20);
           GetDat(s,21,31);
         end;
       Inc(Result,1);
     end;
   CloseFile(f);
//*************************************
// Получаем количество строк в файле
//*************************************
   AssignFile(f, Full);
   Reset(f);
   while not EOF(f) do
     begin
       ReadLn(f, s);
       Inc(KolStr,1);
     end;
     KolStr:=KolStr-4;
CloseFile(f);
//*******************
   Result:=1;
   AssignFile(f, Full);
   Reset(f);
   while not EOF(f) do
     begin
       ReadLn(f, s);
         if Result>=5 then
           begin
             Form1.Table1.Append;
             Form1.Table1.FieldByName('DATEN').AsDateTime:=StrToDateTime(ResultDat);
             Form1.Table1.FieldByName('NOMN').AsString:=ResultNom;
             //Отсюда начинается сама накладная
             //Получим количество полей
             GetFields(s, Length(s));

           end;
       Inc(Result,1);
     end;
   CloseFile(f);
   DeleteFile(Full);
   Form1.Table1.Active:=False;
end;

procedure TMonDirThread.Execute;
Type  PFileNotifyInformation=^TFileNotifyInformation;
     TFileNotifyInformation=packed record
     NextEntryOffset:dword;
     Action:dword;
     FileNameLength:dword;
     FileName:WideChar;
   end;
var hDir,cbReturn:dword;
   lpBuf:pointer;
   Ptr:PFileNotifyInformation;

begin

//Path:='D:\Накладные';
hDir:=CreateFile(Path,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
while not Terminated do
begin
 ZeroMemory(lpBuf,BUF_SIZE);
 if(not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME
 or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil))or(cbReturn=0)then Break;
 // пользователь не сможет прервать ожидание, если захочет. Это нужно либо вынести в отдельный
 // поток, либо использовать синхронный ввод/вывод
 Ptr:=lpBuf;OldName:='';
//  repeat
while not Terminated do
begin
 GetMem(FileName,Ptr^.FileNameLength+2);
 ZeroMemory(FileName,Ptr^.FileNameLength+2);
 lstrcpynW(FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
 case Ptr.Action of
   FILE_ACTION_ADDED:Synchronize(UpdateLog);

 end;
 FreeMem(FileName);
 if Ptr^.NextEntryOffset=0 then break;
 Inc(integer(Ptr),Ptr^.NextEntryOffset);
//  until false;
//until false;
end;
end;
FreeMem(lpBuf); // этот код ни разу не вызывается - программа останется в цикле до первой ошибки
CloseHandle(hDir);

end;



После выполнения FILE_ACTION_ADDED:Synchronize(UpdateLog);
не возвращается в цикл. Почему однако ???


petvv   (2009-03-17 10:16:00) [21]

Вот:


constructor TMonDirThread.Create(aPath: String);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FPath := aPath;
 Self.Priority := tpHighest;
 Resume;
end;
procedure TMonDirThread.UpdateLog;
begin
 Synchronize(TxtToDbf);
end;

procedure TMonDirThread.Execute;
Type  PFileNotifyInformation=^TFileNotifyInformation;
     TFileNotifyInformation=packed record
     NextEntryOffset:dword;
     Action:dword;
     FileNameLength:dword;
     FileName:WideChar;
   end;
var hDir,cbReturn:dword;
   lpBuf:pointer;
   Ptr:PFileNotifyInformation;

begin

//Path:='D:\Накладные';
hDir:=CreateFile(Path,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
while not Terminated do
begin
 ZeroMemory(lpBuf,BUF_SIZE);
 if(not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME
 or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil))or(cbReturn=0)then Break;
 // пользователь не сможет прервать ожидание, если захочет. Это нужно либо вынести в отдельный
 // поток, либо использовать синхронный ввод/вывод
 Ptr:=lpBuf;OldName:='';
//  repeat
while not Terminated do
begin
 GetMem(FileName,Ptr^.FileNameLength+2);
 ZeroMemory(FileName,Ptr^.FileNameLength+2);
 lstrcpynW(FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
 case Ptr.Action of
   FILE_ACTION_ADDED:Synchronize(UpdateLog);

 end;
 FreeMem(FileName);
 if Ptr^.NextEntryOffset=0 then break;
 Inc(integer(Ptr),Ptr^.NextEntryOffset);
//  until false;
//until false;
end;
end;
FreeMem(lpBuf); // этот код ни разу не вызывается - программа останется в цикле до первой ошибки
CloseHandle(hDir);

end;


Anatoly Podgoretsky   (2009-03-17 10:10:00) [22]

> petvv  (17.03.2009 9:21:04)  [4]

Тебе же сказано, что обращение к VCL должно идти через Synchronize, а ты не приводишь измененого кода. Пока это не сделаешь - говорить о другом нет смысла.


petvv   (2009-03-17 10:05:00) [23]

Направьте на путь истинный


petvv   (2009-03-17 09:21:00) [24]

Сделал следующее:

procedure TMonDirThread.UpdateLog;
begin
 Synchronize(TxtToDbf);
end;
а в
procedure TMonDirThread.Execute;
...
 case Ptr.Action of
   FILE_ACTION_ADDED:Synchronize(UpdateLog);

 end;
end;

Результат тотже :(

Или я чего не так делаю (понимаю) ?


petvv   (2009-03-17 09:10:00) [25]

т.е. не

CreateDBF();
а
Synchonize(CreateDBF);

и т.д.


Anatoly Podgoretsky   (2009-03-17 09:04:00) [26]

> petvv  (17.03.2009 7:52:00)  [0]

Обращение к VCL должно проходить через метод Synchonize


petvv   (2009-03-17 08:01:00) [27]

Т.е. получается, что это одноразовая операция и на следующие поступающие файлы уже не реагирует :(


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо