我现在是这样做的,可能跟你的有些出入。
procedure MThread.Execute;
var
  Evnet: THandle;
begin
  Event := WSACreateEvent;
  WSAEventSelect(SocketA, Event, FD_READ or FD_WRITE or FD_CLOSE);//不要用加“+” 
  //PeekMessage(msg, WM_USER, WM_USER, PM_NOREMOVE);//看需要是否创建线程消息队列
  while True do
  begin
    case MsgWaitForMutipleObjects(1, Event, False, INFINITE, QS_ALLINPUT) of
      WAIT_OBJECT_0:
      begin
        WSAResetEvent(Event); //重置Event信号
        //用winsock.select()来判断是FD_Read, FD_Close, FD_Write信号。
      end; 
      {WAIT_OBJECT_0 + 1: //如果Socket线程意外中断,会使本线程一直处于阻塞状态,所以做这个case,让mainForm,PostThreadMessage(Self.ThreadId, WM_USER, ),发个消息过来,再加上时间的判断,是否断开。
         while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
           dispatchMessage(msg);
      }
  end;  
end;