Verificando a presença do servidor remoting .NET - minha abordagem está correta?

Não é possível definir um tempo limite de conexão em uma chamada remota do .NET. Documentação ocasionalmente se refere aTcpChannel propriedades que supostamente fazem isso, masdiscussões e o mais recentedocs Eu encontrei indicam que isso não é possível. Pode-se definir um tempo limite na própria chamada de comunicação remota, mas não na tentativa de conexão inicial. Você está preso com o tempo limite padrão de 45 segundos.

Por vários motivos, não consigo usar o WCF.

Isso causa um problema quando o servidor remoto desaparece. Se eu tentar fazer uma chamada remota, fico preso por esses 45 segundos. Isso não é bom. Eu quero verificar a presença do servidor de remoting. Pingando com umPingTimeout é a abordagem mais simples, mas quero verificar especificamente o servidor remoto, em oposição a apenas a máquina estar ativa.

Depois de algumas experiências, descobri essa abordagem:

Assincronamente, inicie uma conexão de soquete TCP à porta remota.Aguarde a conclusão da conexão ou um tempo limite para expirar (usando um ManualResetEvent).Se o retorno de chamada assíncrona de conexão tiver êxito, retorne o sucesso. Caso contrário, retorne a falha.

Isso funciona, mas não tenho certeza sobre o uso do meuWaitHandle e soquete. Também gostaria de garantir verificações simultâneas de WRT de thread-safety, o que eu acho que fiz. Meu código está abaixo. Você vê algum problema com a minha abordagem?

private static bool IsChannelOpen(string ip, int port, int timeout)
{
    IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(ip), port);
    Socket client = new Socket(endpoint.AddressFamily,
              SocketType.Stream, ProtocolType.Tcp);
    SocketTestData data = new SocketTestData()
              { Socket = client, ConnectDone = new ManualResetEvent(false) };
    IAsyncResult ar = client.BeginConnect
              (endpoint, new AsyncCallback(TestConnectionCallback), data);

    // wait for connection success as signaled from callback, or timeout 
    data.ConnectDone.WaitOne(timeout);
    client.Close();
    return data.Connected;
}

private static void TestConnectionCallback(IAsyncResult ar)
{
    SocketTestData data = (SocketTestData)ar.AsyncState;
    data.Connected = data.Socket.Connected;
    if (data.Socket.Connected)
    {
        data.Socket.EndConnect(ar);
    }
    data.ConnectDone.Set(); // signal completion
}

public class SocketTestData
{
    public Socket Socket { get; set; }
    public ManualResetEvent ConnectDone { get; set; }
    public bool Connected { get; set; }
}

questionAnswers(2)

yourAnswerToTheQuestion