【发布时间】:2017-06-09 21:55:07
【问题描述】:
我正在编写一个需要等到目录中存在文件的应用程序。我已经尝试了多种方法,唯一有效的解决方案是使用 Sleep/Application.ProcessMessages。
这是我尝试过的:
使用睡眠/Application.ProcessMessages:
Result := False;
for i := 0 to iTimeout do
begin
if FileExists(fileName) do
begin
updateStatus('Conversion Completed');
Result := True;
Break;
end;
updateStatus(Format('Checking for file: %d Seconds', [i]));
Application.ProcessMessages;
Sleep(1000);
end;
此方法有效,但我无法在应用程序等待时关闭它。此外,我宁愿避免使用 Sleep/Application.ProcessMessages 的一些有据可查的问题。
使用 TThread/TEvent:
type
TMyThread = class(TThread)
private
FEventDone: TEvent;
public
constructor Create(CreateSuspended: boolean);
destructor Destroy;
procedure Execute; override;
property EventDone: TEvent read FEventDone;
end;
TformThreading = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
waitThread: TMyThread;
{ Private declarations }
public
{ Public declarations }
end;
var
formThreading: TformThreading;
implementation
{$R *.dfm}
{ TformThreading }
procedure TformThreading.Button1Click(Sender: TObject);
var
res: TWaitResult;
begin
try
waitThread.Start;
res := waitThread.EventDone.WaitFor(INFINITE);
case res of
wrSignaled: ShowMessage('wrSignaled');
wrTimeout: ShowMessage('wrTimeout');
wrAbandoned: ShowMessage('wrAbandoned');
wrError: ShowMessage('wrError');
wrIOCompletion: ShowMessage('wrIOCompletion');
end;
except
on E: Exception do
begin
ShowMessage(E.Message);
end;
end;
end;
procedure TformThreading.FormCreate(Sender: TObject);
begin
waitThread := TMyThread.Create(true);
end;
procedure TformThreading.FormDestroy(Sender: TObject);
begin
waitThread.Free;
end;
{ TMyThread }
constructor TMyThread.Create(CreateSuspended: boolean);
begin
inherited Create(CreateSuspended);
FEventDone := TEvent.Create;
end;
destructor TMyThread.Destroy;
begin
FEventDone.Free;
end;
procedure TMyThread.Execute;
begin
for i := 0 to iTimeout do
begin
if FileExists(fileName) do
begin
FEventDone.SetEvent;
Break;
end;
Application.ProcessMessages;
Sleep(1000);
end;
end;
我似乎无法让它在等待时不冻结我的主线程,但如果我能解决冻结问题,这似乎是正确的方法。
解决问题的最佳方法是什么?
【问题讨论】:
-
您确定声称“需要等到目录中存在文件。唯一有效的解决方案是使用 Sleep/Application.ProcessMessages” 正确吗?我猜
ReadDirectoryChangesW可能在这里工作。 -
链接的答案将在有新闻时发送通知。只需在您的程序中设置一个计时器来显示等待的秒数。
-
waitThread.EventDone.WaitFor(INFINITE);- 当您在 UI 线程处理程序中编写它时,这就是死亡。怎么会期望这个 not 冻结你的程序?不要等待您的线程 - 让 it 在完成时通知主线程。TThread.Queue是一种方法,或者只使用OnTerminate事件。 -
您使用的线程完全错误。您的主线程正在等待线程,这正是您不想想要做的事情。如果您的应用程序必须等到文件存在,那么线程将无济于事;您的应用仍需等待。
标签: multithreading delphi