首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

请问通讯 多线程访问 全局变量 Tlist的有关问题

2012-03-16 
请教通讯 多线程访问 全局变量 Tlist的问题function OnGetPortData(var Buf var BufLen: Integer): Integ

请教通讯 多线程访问 全局变量 Tlist的问题
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 没有控制好 但又不知道 什么地方的问题 请各位老大 帮帮忙看看 先谢了 


[解决办法]
你改成这们的试试,一般像这种从0到count的会出现这种错误 ~~~! 

Delphi(Pascal) code
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;
[解决办法]
使用TThreadList替代TList

访问时使用
Delphi(Pascal) code
var  list: TList;begin  list := ThreadList.LockList;  try    //这里访问List  finally    THreadList.UnlockList;  end;  ...end; 

热点排行