function OnGetPortData(var Buf; var BufLen: Integer): Integer;
QueryResultList: TList; 全局变量
函数是接受到数据进行处理 是多线程的 也就是可能同时存在多个线程调用该函数  TOpQImageResult = record
    OpTagNo: Integer;
    RequestListNo: array[0..20] of Char;  请求的序列号
     RequestResult : array[0..20] of Char; 请求的结果放在里面
  end;
  POpQImageResult = ^TOpQImageResult;
所用到的结构体function OnGetPortData(var Buf; var BufLen: Integer): Integer;
var 
  QueryListNo :string;
  pResult: POpQImageResult;
begin
  QueryListNo:=Copy(FormatDateTime('YYMMDDHHMMSSZZZ', Now), 1, 14); 
  New(pResult);
  pResult^.OpTagNo := 0;
  StrPCopy(pResult^.RequestListNo, QueryListNo);
  EnterCriticalSection(g_RCSResult);
  QueryResultList.Add(pResult);
  LeaveCriticalSection(g_RCSResult);
  dt := Now;
  while ((Now-dt)*24*3600)<30000do //大于30秒认为是超时
  begin
   if pResult =nil then
     Break;
   if pResult^.OpTagNo=1 then   // 判断是否有结果返回
    begin
      IsOK := True;
      Break;
    end;
    Sleep(50);
  end;
  if IsOK then
  begin
    把结果返回
  end;
end;另外建一个单线程 处理请求procedure Tthread1.Execute;
var
   p: POpQImageResult;
begin
  EnterCriticalSection(g_RCSResult);
  try
    if QueryResultList.Count>0 then
    begin
      j:=0;
      for i:=0 to QueryResultList.Count-1 do
      begin
        if Terminated then
        exit;
        pImageResult:= QueryResultList.Items[i-j];
        if pImageResult <> nil then
          if (pImageResult.OpTagNo=1)then
          begin
            QueryResultList.Delete(i-j);
            inc(j);
            dispose(pImageResult);
            pImageResult :=nil;
            InterlockedDecrement(ImgNum);
          end;
      end;
    end;  
  finally
    LeaveCriticalSection(g_RCSResult);
  end;  
  // 以上这段是处理 将全局变量QueryResultList 中OpTagNo标志为1的删掉
 for i:=0 to QueryResultList.Count-1 do
 begin
   p := QueryResultList.Items[i];
   if (p=nil) then Continue;
   if (p<>nil) and (p^.OpTagNo=0) then 
   begin
     //根据p^.RequestListNo查询数据库 得到结果复制给p^.RequestResult  
      然后,执行
      p^.OpTagNo=1;改写标志位   
   end;
 end;     
end;这个服务程序运行一段时间 就会非法地址访问 服务死掉 好郁闷啊 
个人觉得是全局变量QueryResultList 没有控制好 但又不知道 什么地方的问题 请各位老大 帮帮忙看看 先谢了 

解决方案 »

  1.   

    忘记一点 在后面的 for 循环外围 也有
    EnterCriticalSection(g_RCSResult); 
    finally 
      LeaveCriticalSection(g_RCSResult); 
    end; 
      

  2.   

    你改成这们的试试,一般像这种从0到count的会出现这种错误 ~~~! 
    if QueryResultList.Count>0 then 
        begin 
          for i:=QueryResultList.Count-1 downto 0  do 
          begin 
            if Terminated then 
            exit; 
            pImageResult:= QueryResultList.Items[i]; 
            if pImageResult <> nil then 
              if (pImageResult.OpTagNo=1)then 
              begin 
                QueryResultList.Delete(i); 
                dispose(pImageResult); 
                pImageResult :=nil; 
                InterlockedDecrement(ImgNum); 
              end; 
          end; 
        end;  
      

  3.   

    使用TThreadList替代TList访问时使用
    var
      list: TList;
    begin
      list := ThreadList.LockList;
      try
        //这里访问List
      finally
        THreadList.UnlockList;
      end;
      ...
    end;