2

几年前,对于我的一个应用程序,当某个应用程序必须非常快速地响应某些串行事件时,我将串行处理转移到一个线程中。

它在 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 更改都已完成,就像我在普通主线程版本中所做的那样

现在真正的问题是:

  1. 有人有 tcomport4 在线程中工作吗?
  2. 上面有明显的错误吗?
  3. 还是我需要迁移到不同的组件?

我仍在调试正在发生的事情,但我很着急,这是我发布这个希望快速获得指针的时候。

更新

我重新安装了一个旧的 turbo delphi 副本,并验证它与 v3 一起工作。我在代码路径中修复了一个小错误,它与我的想法有点不同(不是在上面的代码中)

这让我可以更好地描述 dxe/comportv4 和 bds2006/comportv3 之间的行为;v4 代码生成更多的读取事件(数百次/秒)。似乎读取并没有从传入队列中删除读取的字符。

更新 2

我对最新版本进行了快速测试,并进行了必要的重新排列(杀死字符串函数用于本质上的二进制协议)。我被卡住了一段时间,因为应用程序在启动时崩溃了,但那是因为我使用了 gnugettext,而 Comport 打包了一个不同的(甚至非 unicode?)版本。但在那之后它起作用了

不幸的是,这些更改传播回生产版本(完全编写的协议解码)有点冒险,所以我必须测试中间版本(4.0 和 4.11f 之间)。我会在适当的时候这样做,有什么建议是最后一个 readstr(ansistring) 版本吗?

更新 3

最后,我只是简单地重命名了 4.11f 单元并将它们与旧版本并行使用,将 4.11f 用于线程代码库,将旧版本用于维护现有代码。

从长远来看,我可能会简单地采用 waitforevent 代码并制作自己的版本。它的主要问题是无法查看等待是否在超时、停止事件或其他情况下终止。这意味着如果您想定期发送,则需要另一个计时器。

4

1 回答 1

1

您需要在此处升级到最新的稳定 4.11 版本。

于 2011-12-19T20:44:04.373 回答