几年前,对于我的一个应用程序,当某个应用程序必须非常快速地响应某些串行事件时,我将串行处理转移到一个线程中。
它在 BDS2006 中,具有较旧的版本(一些 3.x?)它是通过在 tthread.execute 中有这样的代码来完成的:
while ...
begin
events:=[evRxChar];
{ Prepare a stop event for killing a waiting communication wait. }
try
comport1.WaitForEvent(events,stopevent.handle,500);
if evRxChar in events then
ComPort1RxChar(comport1,comport1.InputCount); // method of thread.
on e: exception do {only logs} ;
end;
初始化就像
procedure TSerThread.initcomport(comportname:string='COM1');
begin
comport1:=tcomport.create(nil);
ComPort1.BaudRate:=br115200;
ComPort1.DataBits:=dbEight;
ComPort1.Port:=comportname;
ComPort1.StopBits:=sbOneStopBit;
ComPort1.Events:=[];
ComPort1.Connected:=true;
StopEvent := TEvent.Create(nil,{ManualReset}false,{InitialState}false,'StopEvent');
end;
rxchar 方法使用 comport1.readstr() 读取
我最近不得不对此进行挖掘,并注意到它在具有 tcomport4 的 Delphi XE 中不起作用。查看源代码我看到comport4已经改变了它处理其内部线程(“重叠”属性)的方式,但默认似乎是“true”有一个评论“经典”,我
假设这意味着与旧版本兼容。
请注意,协议是二进制的,并且所有 string,char<-> ansistring,ansichar 更改都已完成,就像我在普通主线程版本中所做的那样
现在真正的问题是:
- 有人有 tcomport4 在线程中工作吗?
- 上面有明显的错误吗?
- 还是我需要迁移到不同的组件?
我仍在调试正在发生的事情,但我很着急,这是我发布这个希望快速获得指针的时候。
更新
我重新安装了一个旧的 turbo delphi 副本,并验证它与 v3 一起工作。我在代码路径中修复了一个小错误,它与我的想法有点不同(不是在上面的代码中)
这让我可以更好地描述 dxe/comportv4 和 bds2006/comportv3 之间的行为;v4 代码生成更多的读取事件(数百次/秒)。似乎读取并没有从传入队列中删除读取的字符。
更新 2
我对最新版本进行了快速测试,并进行了必要的重新排列(杀死字符串函数用于本质上的二进制协议)。我被卡住了一段时间,因为应用程序在启动时崩溃了,但那是因为我使用了 gnugettext,而 Comport 打包了一个不同的(甚至非 unicode?)版本。但在那之后它起作用了。
不幸的是,这些更改传播回生产版本(完全编写的协议解码)有点冒险,所以我必须测试中间版本(4.0 和 4.11f 之间)。我会在适当的时候这样做,有什么建议是最后一个 readstr(ansistring) 版本吗?
更新 3
最后,我只是简单地重命名了 4.11f 单元并将它们与旧版本并行使用,将 4.11f 用于线程代码库,将旧版本用于维护现有代码。
从长远来看,我可能会简单地采用 waitforevent 代码并制作自己的版本。它的主要问题是无法查看等待是否在超时、停止事件或其他情况下终止。这意味着如果您想定期发送,则需要另一个计时器。