使用Delphi中的线程在串行端口组件TComPort(v4)中使用事件? [英] Using the Events in a serial port component TComPort (v4) from a thread in Delphi?

查看:54
本文介绍了使用Delphi中的线程在串行端口组件TComPort(v4)中使用事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A few years back for one of my applications I moved my serial handling to a thread when a certain app had to respond very quickly to certain serial events.

它是在BDS2006中,具有较旧的版本(约3.x?),是通过在tthread.execute中包含这样的代码来完成的:

It was in BDS2006, with an older version (some 3.x?) It was done by having code like this in the 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()

The rxchar method reads using comport1.readstr()

我最近不得不对此进行挖掘,并发现它在具有tcomport4的Delphi XE中不起作用.在源代码中,我看到了这样的评论:comport4更改了处理内部线程的方式(重叠"属性),但是默认值似乎是"true",注释为"classic",我

I recently had to dig this up, and noticed it didn't work in my Delphi XE, which has tcomport4. Looking in the source I saw remarks that comport4 has changed the way it deals with its internal threads ("overlapped" property), but the default seems to be "true" has a comment "classic", and I

假定与旧版本兼容.

请注意,协议是二进制的,并且所有字符串,char<-> ansistring,ansichar的更改均已完成,就像我在普通主线程版本中所做的一样

Note that the protocols are binary, and all string,char<-> ansistring,ansichar changes have been done like I did in the normal mainthread version

现在真正的问题:

  1. 有人在线程中工作过tcomport4吗?
  2. 以上是否有明显的错误?
  3. 还是我需要迁移到其他组件?

我仍在调试正在发生的事情,但是很着急,这是我发布此消息的希望,以便快速获取指针.

I'm still debugging what is going on, but am in a hurry, which is while I post this in the hope of quickly getting pointers.

更新

我重新安装了旧的turbo delphi副本,并验证了它在v3上是否可以正常工作.我修复了代码路径中的一个小错误,该错误与我的想法有所不同(上面的代码中没有)

I reinstalled an old turbo delphi copy, and verified it worked there with v3. I fixed a small bug though in the codepath that went a bit different from what I thought (not in the above code)

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

This allows me to describe the behaviour between dxe/comportv4 and bds2006/comportv3 better; the v4 code generates much more read events (hundreds/second). It seems that the read doesn't delete the read chars from the incoming queue or so.

更新2

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

I did a quick test with the newest version, and did the necessary rearranging (kill string function use for an essentially binary protocol). I got stuck for a while because the application crashed on startup, but that is because I use gnugettext, and Comport packages a different (non unicode even?) version. But after that it works.

不幸的是,所做的更改要传播回生产版本(完全编写协议解码)会有一定的风险,因此,我将必须在介于4.0和4.11f之间的版本之间进行测试.我会在适当的时候这样做,是否有任何建议是最后一个readstr(ansistring)版本?

Unfortunately the changes are a bit to risky to propagate back to the production version (completely written protocol decoding), so I'll have to test with inbetween versions (between 4.0 and 4.11f). I'll do that in due time, any suggestion which version was the last readstr(ansistring) one?

更新3

最后,我只是简单地重命名了4.11f单元,并将其与旧版本并行使用,将4.11f用于线程化的代码库,而旧版本则用于维护现有代码.

In the end I simply renamed the 4.11f units and use them in parallel to the old version, using the 4.11f for the threaded codebases and the old one to maintain existing code.

从长远来看,我可以简单地使用waitforevent代码并创建自己的版本.这样做的主要问题是,无法确定等待是否在超时,stopevent或其他条件下终止.这意味着您需要另一个计时器,例如定期发送.

Long term I might simply take the waitforevent code and make an own version. The main problem with it is that it is afaik not possible to see if the wait terminated on timeout, stopevent or whatever. This means you need another timer if you want to e.g. send on regular intervals.

推荐答案

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

You need to upgrade to the latest stable 4.11 release here.

这篇关于使用Delphi中的线程在串行端口组件TComPort(v4)中使用事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆