【问题标题】:Does TTimer.OnTimer causes a worker thread to synchronize with a main thread?TTimer.OnTimer 是否会导致工作线程与主线程同步?
【发布时间】:2011-12-28 09:33:46
【问题描述】:

我必须使用遗留代码。此代码在主线程中创建了一个TTimer。 在OnTimer 事件中,计时器定期检查工作线程中某些数据的状态。

伪代码:

procedure MainForm.OnTimer(Sender: TObject);
begin
  if WorkerThread.Data.State = full then
  begin
    WorkerThread.Free; //This freezes GUI.    
  end else
   //Do something else.
end;

问题是我想在WorkerThread 终止时进行一些后台操作。为了避免同步,我重写了DoTerminate 方法。但是在这种特殊情况下,这并没有帮助,我的 GUI 会冻结,直到 DoTerminate 完成。

我能以某种方式避免冻结吗?

谢谢。

【问题讨论】:

  • 那么你在 DoTerminate 中做什么?
  • 一些数据库的东西。我没有与 GUI 同步。
  • 这里没有足够的代码。在线程上调用 Free 调用 Terminate,然后调用 WaitFor。这可以解释冻结吗?
  • 更多代码。线程执行方法会很好。您可以在帖子中将任何机密内容替换为“SOME SQL”、“打开数据库连接”或类似内容,这样我们就可以在不违反任何 NDA/其他任何内容的情况下查看正在发生的事情。
  • 您的代码显式冻结 GUI 线程,直到 WorkerThread 终止。你还能期待什么?

标签: multithreading delphi timer delphi-2009


【解决方案1】:

这里没有足够的代码来确定任何事情。但是,在线程上调用Free 会导致调用Terminate,后跟WaitFor。等待没有返回是很合理的,这与冻结的 UI 一致。

【讨论】:

    【解决方案2】:

    这确实是倒退。在任何体面的线程方案中,您的线程将通知您的 gui 线程有关 .Data.State = full 之类的条件。然后您的 gui-thread 或 main-thread 将采取适当的措施。我可以肯定的一件事是 WorkerThread.Free 一定是错的。尝试释放显然因任何原因而被阻塞的线程肯定会失败。如果线程被阻塞,Thread.Terminate 也会失败,所以也没有帮助。

    让 Timer 监视线程的状态是不对的。我从不使用“总是”和“从不”这两个词,但是……我再重复一遍:让计时器监视线程的状态是不对的。永远不能。想都别想。

    • 都灵

    【讨论】:

    • 我不同意,至少部分不同意。对于检查状态,计时器是一个很好的低优先级手段,它允许线程继续处理业务,无论主线程在做什么。但我确实同意这是一个不好的用途,因为它不仅显示状态,而且还积极控制。
    • @Turin 我同意这几乎永远不会正确。但正如我之前写的,它是一个遗留代码,并且计时器从一开始就在那里。
    猜你喜欢
    • 2021-01-31
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 2013-11-03
    相关资源
    最近更新 更多