multithreading - 使用CPort进行线程化

标签 multithreading delphi port pascal

我正在尝试在delphi中编写一个简单的CPort应用程序。

我希望它监听端口,收到消息后,它将等待4秒钟,然后发送一个字符串作为响应。

unit Tests.Mocks.Refractometer;

interface

uses
  CPort,
  Classes
  ;

type
  TRefractometerMock = class
    strict private
      MockRunThread : TThread;
      ComPort : TComPort;
      ComDataPacket: TComDataPacket;
    public
      procedure Open;
      procedure HandlePacket(Sender : TObject; const Str : String);

      constructor Create; overload;
      constructor Create(BaudRate : TBaudRate; Port : String); overload;
      destructor Destroy; override;
  end;

implementation

uses
  SysUtils,
  StrUtils
  ;

procedure TRefractometerMock.HandlePacket(Sender : TObject; const Str : String);
begin
    MockRunThread.Start;    
end;

procedure TRefractometerMock.Open;
begin
    ComPort.Open;
end;

constructor TRefractometerMock.Create(BaudRate : TBaudRate; Port : String);
begin
    Self.Create;
    Self.ComPort.Port := Port;
    Self.ComPort.BaudRate := BaudRate;
end;

constructor TRefractometerMock.Create;
begin
    inherited;
    ComPort := TComPort.Create(nil);
    ComDataPacket := TComDataPacket.Create(nil);

    ComDataPacket.ComPort := ComPort;
    ComDataPacket.OnPacket := HandlePacket;

    MockRunThread := TThread.CreateAnonymousThread
    (
        procedure
        begin
            Sleep(4000);
            Self.ComPort.WriteStr('nD=1.33308;');
        end
    );
end;

destructor TRefractometerMock.Destroy;
begin
    if Assigned(Self.ComPort)  then FreeAndNil(Self.ComPort);
    if Assigned(ComDataPacket) then FreeAndNil(ComDataPacket);
    if Assigned(MockRunThread) then FreeAndNil(MockRunThread);

    inherited;
end;

end.

使用 native ,我可以使用以下代码

开始听
RefractometerMock := TRefractometerMock.Create(TBaudRate.br9600, 'COM7');
try
    RefractometerMock.Open;

    Sleep(8000);

finally
    FreeAndNil(RefractometerMock);
end;

还要注意,我正在使用com0com在端口COM6COM7之间创建桥梁。

我正在端口COM6上发送腻子消息

问题是,即使我发送了带有腻子的消息,在释放HandlePacket对象之前,不会调用TRefractometerMock方法。

第一的

然后

然后

最后



我什至不知道这怎么可能,因为我以为这个物体已经被破坏了。

最佳答案

您正在通过Sleep(8000)阻塞主线程。这意味着com端口驱动程序无法调用HandlePacket方法。

sleep 结束后,处理任何事情为时已晚,因为一切都已释放。

由于您正在处理匿名线程的生存时间,因此应将FreeOnTerminate属性设置为false。并在匿名线程之后释放com端口。

使用计时器而不是Sleep()调用。

关于multithreading - 使用CPort进行线程化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29271094/

相关文章:

docker - 端口转发 Ubuntu - Docker

java - Android:WAITING几个异步任务完成

c# - 产生将杀死其父进程但进程仍然存在的新进程?

java - ThreadLocal有什么用?

delphi - 如何修改 TComponentProperty 以仅显示下拉列表中的特定项目?

java - php 向 java 服务器发出请求

Java 多线程和安全发布

multithreading - Delphi如何使用线程

delphi - 如何替换备忘录 (FastReport) 中的字符串?

sockets - 我们可以使用 IP 地址和进程 ID 组合来代替 IP 地址和端口号吗?为什么以及为什么不呢?