2009-05-18 15 views
13

Estoy buscando agregar cierta flexibilidad a una clase que he creado que establece una conexión con un host remoto y luego realiza un intercambio de información (un apretón de manos). La implementación actual proporciona una función Connect que establece la conexión y luego bloquea la espera en un evento ManualReset hasta que las dos partes hayan completado el protocolo de enlace.¿Qué es una implementación adecuada de la interfaz IAsyncResult?

He aquí un ejemplo de lo que llamar a mi clase se parece a:

// create a new client instance 
ClientClass cc = new ClientClass("address of host"); 
bool success = cc.Connect(); // will block here until the 
           // handshake is complete 
if(success) 
{ 

} 

..y he aquí una vista de alto nivel simplificada de lo que hace internamente la clase:

class ClientClass 
{ 
    string _hostAddress; 
    ManualResetEvent _hanshakeCompleted; 
    bool _connectionSuccess; 

    public ClientClass(string hostAddress) 
    { 
     _hostAddress = hostAddress;    
    } 

    public bool Connect() 
    { 
     _hanshakeCompleted = new ManualResetEvent(false);    
     _connectionSuccess = false; 

     // start an asynchronous operation to connect 
     // ... 
     // ... 

     // then wait here for the connection and 
     // then handshake to complete 
     _hanshakeCompleted.WaitOne(); 

     // the _connectionStatus will be TRUE only if the 
     // connection and handshake were successful 
     return _connectionSuccess; 
    } 

    // ... other internal private methods here 
    // which handle the handshaking and which call 
    // HandshakeComplete at the end 

    private void HandshakeComplete() 
    { 
     _connectionSuccess = true; 
     _hanshakeCompleted.Set(); 
    } 
} 

Busco en implementar el .NET Classic Async Pattern para esta clase. Al hacerlo, me gustaría ofrecer funciones BeginConnect y EndConnect, y permitir que los usuarios de la clase para escribir código como este:

ClientClass cc = new ClientClass("address of host"); 
cc.BeginConnect(new AsyncCallback(ConnectCompleted), cc); 
// continue without blocking to this line 

// .. 

void ConnectCompleted(IAsyncResult ar) 
{ 
    ClientClass cc = ar.AyncState as ClientClass; 
    try{ 
     bool success = cc.EndConnect(ar); 
     if(success) 
     { 
      // do more stuff with the 
      // connected Client Class object 
     } 
    } 
    catch{ 
    } 
} 

Con el fin de ser capaz de proporcionar esta API Necesito crear una clase que implementa la Interfaz IAsyncResult que devuelve la función BeginConnect y que se pasará a la función EndConnect respectivamente.

Ahora, mi pregunta es: ¿Cuál es una forma adecuada de implementar la interfaz IAsyncResult en una clase?

Una solución obvia sería crear un delegado con una firma coincidente para la función Connect y luego invocar ese delegado asincrónicamente usando BeginInvoke - EndInvoke pero eso no es lo que estoy buscando (no es muy eficiente).

Tengo una idea aproximada de cómo podría hacerlo, pero después de echar un vistazo dentro del framework .NET sobre cómo implementan este patrón en algunos lugares, sentí que sería inteligente preguntar y ver si alguien lo ha hecho con éxito y si Entonces, ¿cuáles son las áreas problemáticas para prestar especial atención?

Gracias!

Respuesta

1

También tiene muchas implementaciones en el BCL (p. Ej. System.Runtime.Remoting.Messaging.AsyncResult) - use el reflector o la fuente de referencia para verificarlos.

Cuestiones relacionadas