Comprobando la presencia del servidor remoto .NET: ¿es correcto mi enfoque?

No es posible establecer un tiempo de espera de conexión en una llamada remota de .NET. Documentación ocasionalmente se refiere aTcpChannel propiedades que supuestamente hacen esto, perodiscusiones y lo mas recientedocs He encontrado que indica que esto no es posible. Uno puede establecer un tiempo de espera en la llamada remota, pero no en el intento de conexión inicial. Estás atascado con el tiempo de espera predeterminado de 45 segundos.

Por varias razones no puedo usar WCF.

Esto causa un problema cuando el servidor remoto desaparece. Si intento hacer una llamada remota, me quedo atascado durante esos 45 segundos. Eso no es bueno. Quiero verificar la presencia del servidor remoto. Haciendo ping con unPingTimeout es el enfoque más simple, pero quiero verificar específicamente el servidor remoto, en lugar de que la máquina esté arriba.

Después de algunos experimentos, he encontrado este enfoque:

Comience de forma asíncrona una conexión de socket TCP al puerto remoto.Espere a que se complete la conexión o que caduque el tiempo de espera (utilizando un ManualResetEvent).Si la conexión async callback tuvo éxito, devolver el éxito. De lo contrario, devolver el fallo.

Esto funciona, pero no estoy seguro de mi uso de miWaitHandle y zócalo. También me gustaría asegurar las comprobaciones concurrentes WRT de seguridad de subprocesos, lo que creo que he hecho. Mi código está abajo. ¿Ves algún problema con mi enfoque?

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; }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta