用Indy TCPServer + ADO 写的一个服务程序,运行一段时间偶尔会出现 Access violation 错误和List index out of bounds 错误。我的情况是这样的,每个线程有自己的ADOConnection,在线程内创建的,线程调用Services里的一个Decode()过程进行数据包的解析,Decode()里动态生成ADOQuery组件进行数据库查询和更新操作,代码大致如下:在Indy线程中创建ADOConnection  TDecodeThread = class(TIdPeerThread)  // indy thread used to decoding the data pack
  protected
    FADOConn: TADOConnection;
    procedure BeforeExecute; override;
    procedure AfterExecute; override;
  end;procedure TDecodeThread.BeforeExecute;
begin
   CoInitialize(nil);
   FADOConn := TADOConnection.Create(nil);
   FADOConn.LoginPrompt := False;
   FADOConn.ConnectionString := ConnStr;
end;procedure TDecodeThread.AfterExecute;
begin
  if Assigned(FADOConn) then
  begin
    FADOConn.Connected := False;
    FreeAndNil(FADOConn);
  end;
  CoUnInitialize;
end;
在Service中的TCPServer元件的Execute中调用Decode()进行数据的处理
//TDataServer = class(TService)procedure TDataServer.TCPServerExecute(AThread: TIdPeerThread);
var
 str,strtemp:string;
 ActClient: PClient;
begin
  if AThread.Connection.Connected and (not Athread.Terminated) then
  begin
    ActClient := Pointer(AThread.Data);
    ActClient.Time_LastAction := Now;     str := AThread.Connection.CurrentReadBuffer;    if str <> '' then
    begin
      DecodeDataPack(FADOConn,str);
    end;
  end;
end; Decode过程动态生成ADOQuery进行查询和更新
procedure TDataServer.DecodeDataPack(ADBConn: TADOConnection; ADataPack: string);
var
  ADOQry: TADOQuery;
begin
  try
    ADOQry := TADOQuery.Create(nil)
    with ADOQry do
 begin
   Connection := ADBConn;
   Close;
   SQL.Clear;
   SQL.Text := 'sql text';
   Open; 
   //...
   Close;
   SQL.Clear;
   SQL.Text := 'sql text'
   ExecSQL;
 end;
  finally
    ADOQry.Free;
  end;  
 end;
出现的问题如下:
1、运行一段时间偶尔出现 List index out of bounds 错误
2、运行一段时间经常性出现 Access violation at address 00000000. Write of address 00000000 和 Access violation at address 00426F63 in module 'dgprs.exe'. Read of    
      address 00000015 错误请各位帮忙分析分析原因,线程里访问Service中的Decode()过程是否存在冲突的问题?谢谢!

解决方案 »

  1.   

    //TDataServer = class(TService)procedure TDataServer.TCPServerExecute(AThread: TIdPeerThread);
    var
     str,strtemp:string;
     ActClient: PClient;
    begin
      if AThread.Connection.Connected and (not Athread.Terminated) then
      begin
        ActClient := Pointer(AThread.Data);
        ActClient.Time_LastAction := Now;     str := AThread.Connection.CurrentReadBuffer;    if str <> '' then
        begin
          DecodeDataPack(FADOConn,str); //楼主这里的FADOConn是从那里来的?
        end;
      end;
    end; 先判断一下 
    if Assigned(FADOConn) then
       DecodeDataPack(FADOConn,str); 
      

  2.   

    不好意思 代码贴的太组略了 重贴一下://TDataServer = class(TService)procedure TDataServer.TCPServerExecute(AThread: TIdPeerThread);
    var
     str,strtemp:string;
     ActClient: PClient;
    begin
      if AThread.Connection.Connected and (not Athread.Terminated) then
      begin
        ActClient := Pointer(AThread.Data);
        ActClient.Time_LastAction := Now;     str := AThread.Connection.CurrentReadBuffer;    if str <> '' then
        begin
          with TDecodeThread(AThread) do
          begin 
            if Assigned(FADOConn) then //程序中已考虑这个
              DecodeDataPack(FADOConn,str);
          end;
        end;
      end;
    end;