Multithreading 带CPort的线程
我正在尝试用delphi编写一个简单的应用程序 我希望它监听一个端口,在收到消息后,它将等待4秒钟,然后发送一个字符串作为响应Multithreading 带CPort的线程,multithreading,delphi,port,pascal,Multithreading,Delphi,Port,Pascal,我正在尝试用delphi编写一个简单的应用程序 我希望它监听一个端口,在收到消息后,它将等待4秒钟,然后发送一个字符串作为响应 unit Tests.Mocks.Refractometer; interface uses CPort, Classes ; type TRefractometerMock = class strict private MockRunThread : TThread; ComPort : TComPort;
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.
使用此单元,我可以使用以下代码 开始听
RefractometerMock := TRefractometerMock.Create(TBaudRate.br9600, 'COM7');
try
RefractometerMock.Open;
Sleep(8000);
finally
FreeAndNil(RefractometerMock);
end;
还要注意,我正在使用创建端口COM6
和COM7
之间的网桥
我正在端口COM6上发送putty消息
问题是,即使我用putty发送了一条消息,HandlePacket
方法也不会被调用,直到TRefractometerMock
对象被释放
首先
然后
然后
最后
我甚至不确定这是怎么可能的,因为我认为这个对象已被销毁。我没有看到ComDataPacket的任何设置。从帮助:当出现一种停止条件时,数据包结束
。您是否定义了这些停止条件?
您是否在简单的独立应用程序中使用ComDataPacket检查数据接收,而不使用中间类
顺便说一句,TTimer似乎可以完成这项工作,这里不需要线程。您正在通过Sleep(8000)
阻塞主线程。这意味着com端口驱动程序无法调用HandlePacket
方法
当睡眠结束时,处理任何事情都为时已晚,因为一切都被释放了
由于您正在处理匿名线程的生存期,因此应该将FreeOnTerminate
属性设置为false。并在匿名线程之后释放com端口
使用计时器而不是Sleep()
调用。因为Brian Frost想要这里的代码,所以它太大了,无法放入注释中
创建一个简单的表单
type
TFrmMockRefrac = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
RefractometerMock : TRefractometerMock;
{ Public declarations }
end;
var
FrmMockRefrac: TFrmMockRefrac;
在不使用Sleep
功能的情况下处理创建和销毁
procedure TFrmMockRefrac.FormCreate(Sender: TObject);
begin
RefractometerMock := TRefractometerMock.Create(TBaudRate.br9600, 'COM7');
RefractometerMock.Open;
end;
procedure TFrmMockRefrac.FormDestroy(Sender: TObject);
begin
FreeAndNil(RefractometerMock);
end;
你没有启动线程。匿名线程被创建为挂起。您需要调用MockRunThread.Start@AllenBauerMockRunThread.Start
在HandlePacket
函数中被调用。当从com端口接收到数据包时,应调用此函数。至少,这是我希望发生的。@sav:CPort和TAnonymousThread的组合是一个有用的参考。你能用陆路的mods发布你更正的代码吗?谢谢你给我指向com0com的指针。我真的不知道如何用定时器来实现这一点。也许如果我将此代码添加到表单中,而不是从控制台应用程序调用它