如何在单独的线程上执行某些命令?

时间:2009-10-02 09:46:13

标签: multithreading delphi network-programming

允许对象在线程上执行方法的最佳解决方案是什么?该对象是TThread的所有者,该线程仅包含一个TidHTTP(阻塞套接字)来发布请求并解析响应。

示例:

  • 对象>在线程上执行请求
  • 主题>通过idHTTP发送请求,等待响应,将结果发送到对象
  • 主题>等待另一个请求
  • 对象>根据请求的结果更新UI

3 个答案:

答案 0 :(得分:4)

与线程通信的一种相对安全的方法是使用命令队列。

  • 对象在队列中发布请求(使用信号量)。
  • 胎面检查队列(使用信号量),如果填充,则执行最早的请求(您可以 如果你愿意,可以介绍优先事项。
  • 如果任务完成,则会发信号通知对象(例如,使用回调函数)。

线程通常会休眠,只会唤醒以检查队列。如果无事可做,它会“按下贪睡按钮”并再次睡觉。

确保使用信号量保护对队列的访问。否则,存在数据损坏的可能性,并且您有一个难以找到的错误。

答案 1 :(得分:1)

另一种值得一提的方法是使用Andreas Hausladen的Async Calls。它是一个易于使用且编写良好的线程包装器,在功能环境中运行良好。

答案 2 :(得分:0)

我不知道“最好” - 取决于你的标准。如果您稍微扩展一下您的要求,我们可以提供更具体的帮助。在此期间......

最简单的方法是允许拥有对象将请求写入一个或多个属性或通过公共方法写入线程。主Execute例程不直接访问属性/方法后面的数据字段:使用Synchronize()调用的方法将这些数据字段复制到Execute()例程可以使用的变量中。当速度不是主要目标时,我使用此方法,并且拥有对象不需要排队多个请求。

许多人贬低使用Synchronize,但这取决于您尝试实现的功能。我试图保持简单,直到需求要求为止。

如果吞吐量问题更多,或者您需要重叠请求,则可以使用队列来存储请求,并可以访问由TCriticalSection控制的队列。您也可以直接使用TThreadList或作为您自己的类型存储的基础 - 我不知道TThreadList的通用等价物,尽管可能有一个。