Je cherche à ajouter une certaine flexibilité à une classe que j'ai créée qui établit une connexion à un hôte distant et effectue ensuite un échange d'informations (une poignée de main). L'implémentation actuelle fournit une fonction Connect qui établit la connexion, puis bloque l'attente sur un ManualResetEvent jusqu'à ce que les deux parties aient terminé l'établissement de la liaison.Qu'est-ce qu'une implémentation correcte de l'interface IAsyncResult?
Voici un exemple de ce qui appelle ma classe ressemble à:
// 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)
{
}
..et est ici une simplificatrice vue de haut niveau de ce que la classe fait en interne:
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();
}
}
Je suis à la recherche dans la mise en œuvre du .NET Classic Async Pattern pour cette classe. Ce faisant, je fournirais les fonctions BeginConnect et EndConnect, et permettre aux utilisateurs de la classe d'écrire du code comme ceci:
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{
}
}
Afin d'être en mesure de fournir cette API je dois créer une classe qui implémente la Interface IAsyncResult à renvoyer par la fonction BeginConnect et à transmettre respectivement dans la fonction EndConnect. Maintenant, ma question est: Quelle est la bonne façon d'implémenter l'interface IAsyncResult dans une classe? Une solution évidente serait de créer un délégué avec une signature correspondante pour la fonction Connect, puis d'appeler ce délégué de manière asynchrone en utilisant BeginInvoke - EndInvoke mais ce n'est pas ce que je recherche (ce n'est pas très efficace). J'ai une idée approximative de comment je pourrais le faire mais après avoir jeté un coup d'oeil dans le cadre de .NET à la façon dont ils mettent en application ce modèle dans quelques endroits j'ai estimé qu'il serait sage de demander et voir si quelqu'un a fait ceci avec succès Alors, quels sont les domaines problématiques à accorder une attention particulière.
Merci!