运行 在线程内运行并获取结果
Run function inside a thread and get result
我有 2 个函数可以通过检查文件的大小来告诉我文件是否正在使用 grows.In 为了工作我需要在从相同文件收集的每个大小之间使用 5000 毫秒的延迟file.This 没问题,但它阻塞了我的主线程,所以我必须将函数放在线程中。这是我使用的功能。如何创建一个线程来执行函数并获取结果?以下是我目前使用的功能。谢谢!
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;
部分选项:
- 停止使用线程并替换为间隔为 5000 毫秒的计时器。
- 将共享事件对象用于线程安全信号。
- 使用共享布尔值。这将有一场数据竞赛,但是是良性的。
- Post 向主线程发送消息作为通知。
- 使用
TThread.Synchronize
进行同步通知。
我成功完成了这项工作,并将图形用户界面与结果同步。在一个列表框中,我保留正在使用的文件,在另一个列表框中,我保留可以处理的文件。以下线程解决了 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;
我有 2 个函数可以通过检查文件的大小来告诉我文件是否正在使用 grows.In 为了工作我需要在从相同文件收集的每个大小之间使用 5000 毫秒的延迟file.This 没问题,但它阻塞了我的主线程,所以我必须将函数放在线程中。这是我使用的功能。如何创建一个线程来执行函数并获取结果?以下是我目前使用的功能。谢谢!
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;
部分选项:
- 停止使用线程并替换为间隔为 5000 毫秒的计时器。
- 将共享事件对象用于线程安全信号。
- 使用共享布尔值。这将有一场数据竞赛,但是是良性的。
- Post 向主线程发送消息作为通知。
- 使用
TThread.Synchronize
进行同步通知。
我成功完成了这项工作,并将图形用户界面与结果同步。在一个列表框中,我保留正在使用的文件,在另一个列表框中,我保留可以处理的文件。以下线程解决了 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;