一个线程的问题,终于搞定了。

博客讲述了作者在使用TCP连接时遇到的一个线程问题,即线程在接收数据后停止运行。通过详细分析代码,特别是`Synchronize(HandleInput)`导致的阻塞,作者发现是同步调用阻碍了线程的继续执行。将同步调用改为发送消息解决了这个问题,确保线程能够持续运行并接收数据。

昨天调了一下午加一晚上,原来是这样。

线程函数
procedure TTCPClientHandleThread.Execute;
begin
  ……
    while not Terminated do
    begin
        if FIdTCPClient.Connected then
        begin
            try
                 FRxString := FRxString + FIdTCPClient.ReadChar;
                 FEndOfPacket := False;
            except
                if not FEndOfPacket then
                begin
                    FEndOfPacket := True;
                    FDataList.data := FRxString;
                    
Synchronize(HandleInput); //就是这句
                     //改成发消息了 
                     //PostMessage(ReceiveHandle, WM_TCPRECEIVEDATA, 0, 0);

                    FRxString := '';
                end;
           end;
        end;
     end
    else
    begin
      CodeSite.SendMsg('TTCPClientHandleThread:未连接');
      sleep(1000);
    end;
  end;
end;

procedure TTCPClientHandleThread.HandleInput;
begin
  //下面触发事件,然后FOnReceiveData里面继续触发,一直到把数据解析完
  if Assigned(FOnReceiveData) then
    FOnReceiveData(self, PChar(FRxString), Length(FRxString));
end;

基本功能
一个用来接收数据的线程。
Indy的阻塞方式用起来很别扭,tcp读数据非要给定长度,如果缓存里面的数据小于
这个长度,接收就阻塞了。而我需要的功能仅仅是读出缓存里面的所有数据。
没找到直接的实现方法,所以写了这个线程。
循环ReadChar。如果有数据,返回数据。
如果没有数据,ReadChar会阻塞,直到超时,发生异常。
把超时设为100ms或其他数据,这样就可以读到这一段时间内的所有数据。

问题现象:
有的时候能接收,有的时候不能,没有什么明显的规律。
以前写过一个小程序用到这个类,没什么问题。这次放到大系统里面就有问题。
好像第一次接收是正常的,以前程序还能正常用很长时间。
现在第二次接收就收不到了。

找了好久,反复跟踪,感觉是线程第一次接收以后就停了。
以为是suspend或者terminate了,反复查反复查。

最后终于发现,Synchronize(HandleInput)

这句调用了HandleInput,然后触发FOnReceiveData,然后一直触发下去,
直到解析数据并显示。到这句就一直没有返回了。

改成发送消息,线程继续运行。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值