小编HJa*_*Jay的帖子

Delphi:在应用程序退出时杀死线程?

背景:我需要检查一堆网络驱动器或远程计算机是否可用.由于每个都DirectoryExists()需要大量时间直到潜在的超时,我在单独的线程中执行检查.最终用户可能会在某些检查仍在运行时关闭应用程序.由于DirectoryExists()块,我没有机会使用经典while not Terminated方法.

procedure TMyThread.Execute;
begin
  AExists := DirectoryExists(AFilepath);
end;
Run Code Online (Sandbox Code Playgroud)

问题1:当应用程序退出时,某些线程是否仍在运行是否存在问题?Windows会简单地整理一下我就是这样吗?在IDE内部,我收到了未释放对象的通知,但在IDE之外它似乎很平静.

问题2:在这种情况下是否有可能终止这样的简单线程TerminateThread或者这可能是有害的?

问题3:我通常从OnTerminate()事件中的线程获取结果,然后让线程FreeOnTerminate.如果我想自己释放它们,我什么时候应该这样做?我可以在它的OnTerminate事件中释放一个线程,或者这有点太早了?一个线程如何通知我,如果没有,它会被完成OnTerminate

delphi multithreading

7
推荐指数
2
解决办法
1004
查看次数

Delphi TTask WaitForAll 与同步

我只有有限的线程经验。我想并行读取一些基本的数据库表,我需要等到所有表都被读取后才能合理地进行程序。在这方面,阻塞主线程对我来说是可以的。

此代码(简化)工作正常:

procedure ReadDBMultiThread;
  var ATasks : Array of ITask;
begin
  SetLength(ATasks, 3);
  ATasks[0] := TTaskCreate(procedure() begin DB_ReadTable1; end);
  ATasks[1] := TTaskCreate(procedure() begin DB_ReadTable2; end);
  ATasks[2] := TTaskCreate(procedure() begin DB_ReadTable3; end);

  ATasks[0].Start;
  ATasks[1].Start;
  ATasks[2].Start; 

  TTask.WaitForAll(ATasks);
end;
Run Code Online (Sandbox Code Playgroud)

但是,假设我想更新主窗体以显示进度,即已读取哪个数据库表(或执行任何其他必要的主线程工作)。显然,我不能使用 Synchronise(),因为这会导致 WaitForall() 死锁,我不能使用 Queue(),因为它会在 WaitForAll() 完成后执行。

那么,有没有好的解决方案来解决这种“WaitForAll vs Synchronise”的情况?我想,这一定是很多人遇到的情况……需要等待全部完成,但又想更新主线程……

我想过这样的事情,用伪代码给出,替换 WaitForAll() 语句:

repeat 
  Applicaton.ProcessMessages; // or "ProcessSynchroniseMessages"
until "AllTaskCompleted"(ATasks);
Run Code Online (Sandbox Code Playgroud)

这行得通吗?有更好的解决方案吗?

我可以编写像 ProcessMessages 这样的自己的例程,但仅限于同步消息,即其他主窗体事件直到稍后才会执行吗?

提前谢谢了!

delphi multithreading

2
推荐指数
1
解决办法
3139
查看次数

PostThreadMessage:创建一个消息队列

我有一个问题,关于Thread在其生命周期开始时缺少消息队列.MSDN解释道

发布消息的线程必须已创建消息队列,否则对PostThreadMessage的调用将失败.使用以下方法之一来处理这种情况:

(1)调用PostThreadMessage.如果失败,请调用Sleep函数并再次调用PostThreadMessage.重复,直到PostThreadMessage成功.

(2)创建一个事件对象,然后创建该线程.在调用PostThreadMessage之前,使用WaitForSingleObject函数等待事件设置为信号状态.在要将消息发布到的线程中,调用PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)以强制系统创建消息队列.设置事件,以指示线程已准备好接收已发布的消息.

方法(1)解决了我的问题,第二次调用PostThreadMethod()总是在我的应用程序中成功.

但是,我想理解第二种方法并且根本不理解"事件对象"(当然不是正常的Delphi事件?)"以信号状态"和"设置事件指示".

问题:有人可以将段落(2)翻译成一个简短的Delphi代码示例吗?

delphi multithreading delphi-10.2-tokyo

2
推荐指数
1
解决办法
425
查看次数

标签 统计

delphi ×3

multithreading ×3

delphi-10.2-tokyo ×1