在线程内运行函数并获得结果

时间:2015-02-25 11:38:31

标签: delphi delphi-2010

我有2个函数可以通过检查文件大小是否增长来告诉我文件是否正在使用。为了工作,我需要在从同一文件收集的每个大小之间使用5000毫秒的延迟。这是好但是它会阻塞我的主线程所以我必须将函数放在一个线程中。这是我使用的功能。如何创建一个我执行函数并获得结果的线程?以下是我目前使用的功能。谢谢!

function GetFileSize_mmg(const FileName: string): Int64;
var
  fad: TWin32FileAttributeData;
begin
  if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then
    RaiseLastOSError;
  Int64Rec(Result).Lo := fad.nFileSizeLow;
  Int64Rec(Result).Hi := fad.nFileSizeHigh;
end;


function does_size_changes(filename:string; delay:integer;memo_loguri:Tmemo): boolean;
var size1,size2:int64;
begin
result:=false;
size1:=GetFileSize_mmg(filename);
sleep(delay);
size2:= GetFileSize_mmg(filename);

if size1 <> size2 then
begin
result:=true;
memo_loguri.Lines.Add(datetimetostr(now)+' - file "'+filename+'" is growing: ' +inttostr(size1)+' < '+inttostr(size2));
end

else
begin
result:=false;
memo_loguri.Lines.Add(datetimetostr(now)+' - file "'+filename+'" can be used: '+ inttostr(size1)+' = '+inttostr(size2));
end;
end;

2 个答案:

答案 0 :(得分:0)

一些选项:

  1. 停止使用线程并用间隔为5000毫秒的计时器替换。
  2. 使用共享事件对象进行线程安全信令。
  3. 使用共享布尔值。这将有一个数据竞争,但一个良性的。
  4. 将消息作为通知发布到主线程。
  5. 使用TThread.Synchronize进行同步通知。

答案 1 :(得分:-1)

我成功完成了这项工作并将gui与结果同步。在一个列表框中,我保留正在使用的文件,在另一个列表框中,我保留了可以处理的文件。以下线程解决了gui冻结的问题,并且只需5秒即可处理所有文件。我将所有文件加载到列表框(listbox_fisiere_in_uz)。我使用下面的线程检查文件。如果文件的大小没有增长,那么我将它们移动到第二个列表框(ListBox_fisiere_restore_vme)。

function GetFileSize_mmg(const FileName: string): Int64;
var
  fad: TWin32FileAttributeData;
begin
  if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then
    RaiseLastOSError;
  Int64Rec(Result).Lo := fad.nFileSizeLow;
  Int64Rec(Result).Hi := fad.nFileSizeHigh;
end;

type
  TThread_verificare_fisiere_in_uz = class(TThread)
  private
   Variabila_fisier: string;
   variabila_interval_verificare:integer;
    size1, size2: Int64;
    raspuns_verificare_stare_fisier:string;
    test_raspuns:string;
  protected
    procedure Execute; override;
    procedure AfisareRezultat;
  public
    constructor Create(nume_fisier:string;interval:integer);
  end;



constructor TThread_verificare_fisiere_in_uz.Create;
begin
  inherited Create(false);
  Variabila_fisier := nume_fisier;
  variabila_interval_verificare:= interval;
end;

procedure TThread_verificare_fisiere_in_uz.Execute;
begin

  raspuns_verificare_stare_fisier := 'false';
  size1 := GetFileSize_mmg(Variabila_fisier);
  sleep(variabila_interval_verificare);
  size2 := GetFileSize_mmg(Variabila_fisier);



  if size1 <> size2 then
  begin
    raspuns_verificare_stare_fisier := 'true';
    test_raspuns:='Fisierul '+Variabila_fisier+' este in curs de scriere:'+inttostr(size1)+'<>'+inttostr(size2);
     Synchronize(AfisareRezultat);
  end;

  if size1 = size2 then
  begin
    raspuns_verificare_stare_fisier := 'false';
     test_raspuns:='Fisierul '+Variabila_fisier+' nu este in uz'+inttostr(size1)+'='+inttostr(size2);
     Synchronize(AfisareRezultat);
  end;

end;


procedure TThread_verificare_fisiere_in_uz.AfisareRezultat;
var index_fisier_verificat:integer;
    fisier_in_curs_de_verificare:string;
    raspuns:string;

begin
{detectez index-ul fisierului in curs de verificare dupa numele fisierului pe care il verific}
index_fisier_verificat:= form2.ListBox_fisiere_in_uz.Items.IndexOf(variabila_fisier);
fisier_in_curs_de_verificare:= variabila_fisier;
raspuns:= raspuns_verificare_stare_fisier;

 if raspuns_verificare_stare_fisier = 'true' then
  begin
    Form2.Memo_loguri.Lines.Add(datetimetostr(now) +
        ' - dimensiunea fisierului "' + fisier_in_curs_de_verificare + '" creste: ' + inttostr
        (size1) + ' < ' + inttostr(size2) +
        ' => fisierul este in proces de scriere');

  end;

  if raspuns_verificare_stare_fisier = 'false' then
  begin
    Form2.Memo_loguri.Lines.Add(datetimetostr(now) +
        ' - dimensiunea fisierului "' + fisier_in_curs_de_verificare + '" nu se modifica: ' +
        inttostr(size1) + ' = ' + inttostr(size2)
        + ' => fisierul nu este in uz');
    begin


if not exista_textul_in_listbox(Form2.ListBox_fisiere_in_uz.Items[index_fisier_verificat],Form2.ListBox_fisiere_restore_vme) then
        Form2.ListBox_fisiere_restore_vme.Items.Add(Form2.ListBox_fisiere_in_uz.Items[index_fisier_verificat]);


if Form2.ListBox_fisiere_in_uz.Items.count > 0 then Form2.ListBox_fisiere_in_uz.Items.Delete(index_fisier_verificat);
    end
  end;

end;