程序每30秒上传数据到远程数据库,经常出现没有任何提示就退出了!1、当服务器重新启动或关机时,过一段时间程序就会退出
2、有时网络不稳定时,也会出现
2、有时服务器与网络都正常时,也会出现注:客户端6个,分别通过光缆连接至数据中心
部分代码:
procedure TForm1.Timer2Timer(Sender: TObject); //定时上传实时数据
var
  Present: TDateTime;
  Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
  Present := Now;
  DecodeDate(Present, Year, Month, Day);
  DecodeTime(Present, Hour, Min, Sec, MSec);  if (Sec=0) or (Sec=30) then
  begin
    Self.ReadData(Present); //数据量主要在此过程,其它数据量很小
    Self.ReadWarn;
    Self.ReadPD;
    Self.ReadErr;
    Self.ReadKDERR;
    Self.ReadStation;
  end;
end;procedure TForm1.ReadData(UpdateTime: TDateTime);//更新实时数据
var
begin
  if not SQLState then Exit;
  Present := UpdateTime;
  DecodeDate(Present, Year, Month, Day);
  DecodeTime(Present, Hour, Min, Sec, MSec);
  //此处从DLL中读取实时数据
  j := GetUp_RealData(@PFZ,@PDK,@PDKLX,PAZWZ,PSBMC,PDW,@PLCSX,@PLCXX,@PRealData,@PSSPL,@PBJBZ);
  //==========
  SetLength(ZAZWZ,j);
  SetLength(ZSBMC,j);
  SetLength(ZDW,j);
  PA := PAZWZ;
  PC := PSBMC;
  PD := PDW;
  for i := 0 to j-1 do
  begin
    ZAZWZ[i] := PA;
    PA := PA + length(ZAZWZ[i]) + 1;
    ZSBMC[i] := PC;
    PC := PC + length(ZSBMC[i]) + 1;
    ZDW[i] := PD;
    PD := PD + length(ZDW[i]) + 1;
  end;
  //更新实时数据
  if (Sec = 0) or (Sec = 30) then
  begin
    try
      if Self.RemoteQuery.Active then Self.RemoteQuery.Active := False;
      if not Self.RemoteConnection.Connected then Self.RemoteConnection.Connected := True;
      if not Self.RemoteConnection.KeepConnection then Self.RemoteConnection.KeepConnection := True;
      if not Self.RemoteConnection.InTransaction then Self.RemoteConnection.BeginTrans;
      //清空数据
      SqlStr := 'Delete From RealData'; Self.RemoteExecQuery(SqlStr);
        SqlStr := 'Insert Into RealData Values(' + QuotedStr(tempstr) + ',' + QuotedStr(ZAZWZ[i]) + ',' + QuotedStr(ZSBMC[i]) + ',' +QuotedStr(ZDW[i]) + ',' + FormatCurr('0.00',PLCSX[i]) + ','
          + FormatCurr('0.00',PLCXX[i]) + ',' + FormatCurr('0.00',PRealData[i]) + ',' + IntToStr(PSSPL[i]) + ',' + QuotedStr(FormatDateTime('yyyy-mm-dd hh:mm:ss',Present)) + ',' + IntToStr(PBJBZ[i]) + ')';        if SqlStr <> '' then Self.RemoteExecQuery(SqlStr);
      if Self.RemoteConnection.InTransaction then Self.RemoteConnection.CommitTrans;
      if Self.RemoteQuery.Active then Self.RemoteQuery.Active := False;
    except
      on e:Exception do
      begin
        if Self.RemoteConnection.InTransaction then Self.RemoteConnection.RollbackTrans;
        if Self.RemoteQuery.Active then Self.RemoteQuery.Active := False;
        if Self.RemoteConnection.Connected then Self.RemoteConnection.Connected := False;
        Self.StatusBar1.Panels[1].Text := '更新实时数据失败!'+ FormatDateTime('yyyy-mm-dd hh:mm:ss',Present);
        Self.StatusBar1.Refresh;
        SQLState := Self.CheckDBConnection('192.168.0.1');
      end;
    end;
  end;
end;

解决方案 »

  1.   

    还有个时钟,通过判断SQLState标志,定时重新连接DB
      

  2.   

    楼上的意思是DLL调用有问题吗?
      

  3.   

    程序突然关闭问题有很多,不过都是关于内存的,而且stack的原因更大一些,先检查一下有没有堆内存泄露,如果没有那就有可能什么地方使用了递归太深,或是使用socket,THandle之类的变量没有Close使stack异常,往往是这样崩溃的,stack内存不够用了,这时会抛出异常,但就连异常所需要的内存都不够了程序直接崩溃
      

  4.   

    检查下内存泄露吧,同时自己想办法测试下你的每段代码,肯定是有问题的,我这个月初也遇到这个问题,另外还有客户端无故断开。最后发现都是内存的问题。LZ把代码逐步屏蔽吧,写写Log跟一根,总是会查出问题的。
      

  5.   

    已解决,确实是内存问题。之前所有关于DLL的调用是静态调用,改为动态调用DLL后解决问题。