以前的:
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
begin
//
end;
现在的:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  AData: TIdBytes; ABinding: TIdSocketHandle);
begin
//
end;请问这个AThread起什么作用,能否结合例子说明下,非常感谢!

解决方案 »

  1.   

    AThread: TIdUDPListenerThread是哪个监听的线程,这个线程的任务就是不停的接收数据,然后触发OnUDPRead函数,如果你选了ThreadedEvent则OnUDPRead在监听线程中执行,否则用Synchronize到主线程中执行。具体可参考代码:procedure TIdUDPListenerThread.Run;
    var
      PeerIP: string;
      PeerPort : TIdPort;
      ByteCount: Integer;
    begin
      if FBinding.Select(AcceptWait) then try
        // Doublecheck to see if we've been stopped
        // Depending on timing - may not reach here if it is in ancestor run when thread is stopped
        if not Stopped then begin
          SetLength(FBuffer, FServer.BufferSize);
          ByteCount := GStack.ReceiveFrom(FBinding.Handle, FBuffer, PeerIP, PeerPort, FBinding.IPVersion);
          SetLength(FBuffer, ByteCount);
          FBinding.SetPeer(PeerIP, PeerPort, FBinding.IPVersion);
          if FServer.ThreadedEvent then begin
            UDPRead;
          end else begin
            Synchronize(UDPRead);
          end;
        end;
      except
        // exceptions should be ignored so that other clients can be served in case of a DOS attack
        on E : Exception do
        begin
          FCurrentException := E.Message;
          FCurrentExceptionClass := E.ClassType;
          if FServer.ThreadedEvent then begin
            UDPException;
          end else begin
            Synchronize(UDPException);
          end;
        end;
      end;
    end;
      

  2.   

    SQLDebug_Fan: 我把整个功能说一遍,否则不知道选哪个。我用dxMemData做了个内存表,每个几秒钟就有一次更新数据(2万条左右),当然其中还有查询的操作。procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
      AData: TIdBytes; ABinding: TIdSocketHandle);
    var
      Msg: String;
      Info: String;
    begin
      //.....  省略过程
      if Msg = 'Update' then
        UpdateData(IP, Info)
      else if Msg = 'GetInfo' then
        Info := GetInfo(IP); 
    end;procedure TFrom1.UpdateData(const IP, Info: String);
    begin
      try
        dxMemData.DisableControls;
        dxMemData.ProgrammedFilter := False;
        dxMemData.Filtered := False;
        dxMemData.ProgrammedFilter := True;
        dxMemData.First;
        while not dxMemData.Eof do
        begin
          if dxMemData.FieldByName('ip').AsString = IP then
          begin
            dxMemData.FilterList.Add(Pointer(dxMemData.CurRec + 1));
            Break;
          end;
          dxMemData.Next;
        end;
        dxMemData.Filtered := True;
      finally
        dxMemData.EnableControls;
      end;
      
      if not dxMemData.IsEmpty then
      begin
        dxMemData.DisableControls;
        dxMemData.Edit;
        dxMemData.FieldByName('ip').asString := IP;
        dxMemData.FieldByName('info').asString := Info;
        dxMemData.Post;
        dxMemData.EnableControls;
      end else
      begin
        dxMemData.DisableControls;
        dxMemData.Insert;
        dxMemData.FieldByName('ip').asString := IP;
        dxMemData.FieldByName('info').asString := Info;
        dxMemData.Post;
        dxMemData.EnableControls;
      end;
    end;function TFrom1.UpdateData(const IP: String): String;
    begin
      try
        dxMemData.DisableControls;
        dxMemData.ProgrammedFilter := False;
        dxMemData.Filtered := False;
        dxMemData.ProgrammedFilter := True;
        dxMemData.First;
        while not dxMemData.Eof do
        begin
          if dxMemData.FieldByName('ip').AsString = IP then
          begin
            dxMemData.FilterList.Add(Pointer(dxMemData.CurRec + 1));
            Break;
          end;
          dxMemData.Next;
        end;
        dxMemData.Filtered := True;
      finally
        dxMemData.EnableControls;
      end;  dxMemData.First;
      Result := dxMemData.FieldByName('info').asString;
    end;请问是否设置ThreadedEvent = False 以便Synchronize()呢?
      

  3.   

    dxMemData的操作最好是放到子线程来执行,这样在操作的时候,不至于主线程卡死。
      

  4.   

    子线程做的话倒是挺好的方法,但是有个地方我不懂,就是在查询或更新子线程都有这个操作:
    dxMemData.DisableControls;
    .......
    dxMemData.EnableControls;这个需要用Synchronize同步吗?我就是担心这个会影响结果。
      

  5.   

    Synchronize同步是把你操作的代码放到主线程中执行,如果加了ThreadedEvent就是在子线程中执行。
      

  6.   

    嗯,我应该这么问:如果开启了子线程执行,那么如何来确保更新数据、查询数据的一致性。因为dxMemData的更新和查询都用到了
    dxMemData.DisableControls;
    .......
    dxMemData.EnableControls;一个线程A执行到dxMemData.DisableControls;的时候,另一个线程却在执行dxMemData.EnableControls;那样不就影响了A继续往下的功能么?
      

  7.   

    你加了ThreadEvent也只是有一个线程TIdUDPListenerThread在执行,不会有两个线程,如果有多个线程,则要采取同步,或者加入读写池机制来保证效率。
      

  8.   

    加了ThreadEvent后,UDPRead事件里面分了好多情况处理方法。
    case MsgType of
     1: //A.....
     2: //B.....
     3: //C.....
    end;其中A,B,C都有对dxMemData的操作,UDP接包的时候,有触发A,有触发B,也有触发C等。
    既然都是线程触发的,是不是就会存在多个线程呢?那样彼此之间是否就需要同步?非常感谢SQLDebug_Fan!
      

  9.   

    TIdUDPServer不会,但是TIdTCPServer是多线程的。