Delphi(Indy)服务器冻结写入

时间:2012-07-24 05:55:04

标签: delphi client-server indy

我目前在客户端(IdTCPClient)和服务器(IdTCPServer)之间有稳定的代码,它们按计划完成。但是,当我从按钮的OnClick事件调用以下函数时,服务器会冻结。

var
  SendStream: TMemoryStream;
  FileStream: TFileStream;
  List: TList;
  I: Integer;
begin
  try
    //Load
    FileStream := TFileStream.Create(Path, fmOpenRead);
    FileStream.Position := 0;
    //Place into stream
    SendStream := TMemoryStream.Create;
    SendStream.Write(Header, SizeOf(Header)); //This works; supporting code ommitted  for brevity
    SendStream.CopyFrom(FileStream, FileStream.Size);
    SendStream.Position := 0;

    TIdContext(fTCP.Contexts.LockList[0]).Connection.IOHandler.Write(SendStream, 0, True);
    fTCp.Contexts.LockList;
   if Assigned(Self.fServerOnSync) then Self.fServerOnSync(SizeOf(Header)) //event handler for main form

  finally
    FileStream.Free;
    SendStream.Free;
  end;

我猜这与死锁线程有关,但对于我的生活,我不知道它为什么会发生。

另外,如果我将上述代码封装在包含IdTCP服务器的某个类中,该服务器将调用我的自定义fServerOnSync事件,那么这个线程是否安全?

干杯, 阿德里安

1 个答案:

答案 0 :(得分:1)

您正在调用fTCp.Contexts.LockList()两次,但您根本没有调用fTCp.Contexts.UnlockList(),因此每当尝试访问Contexts列表时,服务器就会陷入僵局。锁定后需要解锁列表,例如:

var 
  SendStream: TMemoryStream; 
  FileStream: TFileStream; 
  List: TList; 
  I: Integer; 
begin 
  FileStream := TFileStream.Create(Path, fmOpenRead or fmShareDenyWrite); 
  try 
    SendStream := TMemoryStream.Create; 
    try
      SendStream.Write(Header, SizeOf(Header));
      SendStream.CopyFrom(FileStream, FileStream.Size); 
      SendStream.Position := 0; 

      List := fTCP.Contexts.LockList; 
      try
        TIdContext(List[0]).Connection.IOHandler.Write(SendStream, 0, True); 
      finally
        fTCP.Contexts.UnlockList; 
      end;
      if Assigned(fServerOnSync) then fServerOnSync(SizeOf(Header)); 
    finally 
      SendStream.Free; 
    end; 
  finally
    FileStream.Free; 
  end;
  ...
end;