2009-05-18 4 views
13

Sto cercando di aggiungere una certa flessibilità a una classe che ho creato che stabilisce una connessione a un host remoto e quindi esegue uno scambio di informazioni (una stretta di mano). L'implementazione corrente fornisce una funzione Connect che stabilisce la connessione e quindi blocca l'attesa su un ManualResetEvent fino a quando le due parti non hanno completato l'handshake.Che cos'è un'implementazione corretta dell'interfaccia IAsyncResult?

Ecco un esempio di quello che chiama mia classe si presenta come:

// 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) 
{ 

} 

..e qui c'è una vista di alto livello troppo semplificata di ciò che la classe fa internamente:

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

sto cercando per implementare lo .NET Classic Async Pattern per questa classe. In tal modo, vorrei fornire funzioni BeginConnect e EndConnect, e consentire agli utenti della classe di scrivere codice come questo:

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

Al fine di essere in grado di fornire questa API ho bisogno di creare una classe che implementa il Interfaccia IAsyncResult da restituire dalla funzione BeginConnect e da passare rispettivamente alla funzione EndConnect.

Ora, la mia domanda è: qual è un modo corretto per implementare l'interfaccia IAsyncResult in una classe?

Una soluzione ovvia sarebbe quella di creare un delegato con una firma di corrispondenza per la funzione Connect e quindi richiamare il delegato in modo asincrono utilizzando BeginInvoke - EndInvoke, ma che non è quello che sto cercando (non è molto efficiente).

Ho una vaga idea di come potrei farlo ma dopo aver sbirciato all'interno del framework .NET su come hanno implementato questo modello in alcuni punti ho sentito che sarebbe saggio chiedere e vedere se qualcuno lo ha fatto con successo e se quindi quali sono le aree problematiche su cui prestare particolare attenzione.

Grazie!

risposta

1

Hai anche molte implementazioni nel BCL (ad es. System.Runtime.Remoting.Messaging.AsyncResult) - utilizzare il riflettore o la fonte di riferimento per controllarli.

Problemi correlati