eutilizar soquete assíncrono: tentativas subsequentes de conexão falh

Estou tentando reutilizar um soquete em um cliente HTTP assíncrono, mas não consigo conectar ao host pela segunda vez. Basicamente, trato meu cliente HTTP assíncrono como uma máquina de estado com os seguintes estados:

Disponível: o soquete está disponível para usoConnecting: o soquete está se conectando ao endpoint Enviando: o soquete está enviando dados para o endpointReceiving: o soquete está recebendo dados do endpoint Falha: houve uma falha no soqueteLimpar: limpar o estado do soquete

No estado de conexão eu chamoBeginConnect:

private void BeginConnect()
{
    lock (_sync) // re-entrant lock
    {
        IPAddress[] addersses = Dns.GetHostEntry(_asyncTask.Host).AddressList;

        // Connect to any available address
        IAsyncResult result = _reusableSocket.BeginConnect(addersses, _asyncTask.Port, new AsyncCallback(ConnectCallback), null);
    }
}

O método de retorno de chamada altera o estado paraSending assim que uma conexão bem-sucedida for estabelecida:

private void ConnectCallback(IAsyncResult result)
{
    lock (_sync) // re-entrant lock
    {
        try
        {
            _reusableSocket.EndConnect(result);

            ChangeState(EClientState.Sending);
        }
        catch (SocketException e)
        {
            Console.WriteLine("Can't connect to: " + _asyncTask.Host);
            Console.WriteLine("SocketException: {0} Error Code: {1}", e.Message, e.NativeErrorCode);
            ThreadPool.QueueUserWorkItem(o =>
            {
                // An attempt was made to get the page so perform a callback
                ChangeState(EClientState.Failed);
            });
        }
    }
}

Na limpeza euShutdown o soquete eDisconnect com uma bandeira de reutilização:

private void CleanUp()
{
    lock (_sync) // re-entrant lock
    {
        // Perform cleanup 
        if (_reusableSocket.Connected)
        {
            _reusableSocket.Shutdown(SocketShutdown.Both);
            _reusableSocket.Disconnect(true);
        }
        ChangeState(EClientState.Available);
    }
}

Chamadas subsequentes paraBeginConnect resulta em um tempo limite e uma exceção:

SocketException: uma tentativa de conexão falhou porque a parte conectada não respondeu adequadamente após um período de tempo ou a conexão estabelecida falhou porque o host conectado falhou ao responder XX.XXX.XX.XX: 80

Código de erro: 10060

Aqui está o rastreio de estado:

Initializing...
Change State: Connecting
Change State: Sending
Change State: Receiving
Change State: CleanUp
Callback:     Received data from client 0 // <--- Received the first data 
Change State: Available
Change State: Connecting // <--- Timeout when I try to reuse the socket to connect to a different endpoint

O que devo fazer para reutilizar o soquete para conectar-me a um host diferente?

Nota: eu tenhonã tentou se reconectar ao mesmo host, masEu assum acontece o mesmo (ou seja, falha na conexão).

Atualiza
Encontrei a seguinte nota no documentação do BeginConnect:

Se esse soquete tiver sido desconectado anteriormente, o BeginConnect deverá ser chamado em um encadeamento que não sairá até que a operação seja concluída. Essa é uma limitação do provedor subjacente. Além disso, o EndPoint usado deve ser diferent

Estou começando a me perguntar se meu problema tem algo a ver com isso ... Estou me conectando a um EndPoint diferente, mas o que eles significam que o encadeamento do qual chamamos BeginConnect não deve sair até que a operação seja concluída?

Update 2.0:
Eu perguntei a questão relacionada e tentei usar as chamadas "família assíncrona" em vez das chamadas "família iniciada", mas tenho o mesmo problema !!!

questionAnswers(2)

yourAnswerToTheQuestion