Ric*_*ler 5 delphi events multithreading
我想在示例应用程序中有三个线程.
线程#1(主线程) - 用户界面/ GUI
线程#2 - 连接到通过传递到数据队列的事件接收数据的串行端口设备.
线程#3 - 在创建队列条目时激活,处理数据节点,释放数据对象.
目标是
a)当主窗体上的鼠标按住按钮或表格时,防止数据丢失.
b)快速从事件中获取数据,将其填入队列,重新进入休眠状态
c)处理数据时,否则进入休眠状态.
像AsyncoPro这样的包可以将事件处理绑定到非主线程吗?
我从未对串口事件驱动的应用程序做过多少工作,我所使用的大部分内容都经过轮询,我想做一些测试.
您绝对可以将事件处理与非主线程联系起来.你不能做的是将屏幕更新绑定到非主线程.Windows API不是线程安全的,因此构建在Windows API之上的Delphi VCL也不是.但是你的设计基本上是一个好的,可行的想法; 只记得使用Synchronize或Queue方法TThread发送任何UI更新以在主线程上执行.
最简单的方法是定义一些用户消息,然后将其从子线程发送到主线程.
它完全是线程安全的,甚至是过程安全的.
PostMessage()与主窗体的句柄一起使用.但是不要将此WM_USER+n消息广播到整个UI,因为您可能会混淆定义其自定义消息的VCL的某些部分.
如果要在线程或进程中复制一些文本数据,可以看到WM_COPY_DATA.实际上,这比用于小消息的命名管道快得多,速度更快.
对于用户界面,我发现有时候无状态实现是一个好主意.也就是说,您不通过Synchronize()调用或GDI消息回调主线程,但您的主GUI线程有一个计时器,用于检查共享内存缓冲区是否有挂起的更新.这就是网络的工作方式,在实践中,它很容易使用:你不必编写任何回调,每个线程都是独立的,做自己的东西,并在必要时刷新.
但是,当然,解决方案取决于您的确切项目架构.
对于一个简单但经过验证的库,请参阅AsyncCalls,从Delphi 5到XE.有关IDE的最新版本(Delphi 2007及更高版本),请查看OmniThreadLibrary.通过使用这些库,您将确保您的软件实现不会破坏任何地方:多线程应用程序在大多数情况下按预期工作是很常见的,然后,由于未知原因,进入无限循环.当然,它只发生在客户端,而不是你的......如果你不想花费数小时调试你的程序,那就相信那些已知经过精心设计和调试的成熟库.
当然,您可以通过某种方式做到这一点。自 D5 以来未使用过 Apro - 我的 Apro 不适用于我的 D2009(unicode/string/ANSIstring 问题),并且我有自己的串行类。大多数可用的串行组件都可以选择在 rx 线程或主 GUI 线程上触发 dataRx 事件 - 显然,在您的情况下,您应该选择 rx 线程(线程 #2)。将接收数据推入某个缓冲区类并将其推入生产者-消费者线程(线程 #3)。在那里处理它。如果您需要从那里进行 GUI 更新,请 PostMessage 引用 GUI 线程并在用户定义的消息处理程序过程中处理它。
完成这种事情加载一次-它会工作正常。
Rgds,马丁
| 归档时间: |
|
| 查看次数: |
1591 次 |
| 最近记录: |