私が作成したクラスに柔軟性を追加して、リモート ホストへの接続を確立し、情報交換 (ハンドシェイク) を実行することを検討しています。現在の実装は、接続を確立し、2 つの当事者がハンドシェイクを完了するまで ManualResetEvent で待機することをブロックする Connect 関数を提供します。
クラスの呼び出しがどのように見えるかの例を次に示します。
// 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)
{
}
..そして、クラスが内部で行うことの単純化された高レベルのビューを次に示します。
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();
}
}
このクラスに.NET Classic Async パターンを実装することを検討しています。その際、BeginConnect 関数と EndConnect 関数を提供し、クラスのユーザーが次のようなコードを記述できるようにします。
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{
}
}
この API を提供できるようにするには、BeginConnect 関数によって返され、EndConnect 関数にそれぞれ渡される IAsyncResult インターフェイスを実装するクラスを作成する必要があります。
さて、私の質問は次のとおりです。クラスに IAsyncResult インターフェイスを実装する適切な方法は何ですか?
明らかな解決策の 1 つは、Connect 関数の署名が一致するデリゲートを作成し、BeginInvoke - EndInvoke を使用してそのデリゲートを非同期的に呼び出すことですが、それは私が探しているものではありません (あまり効率的ではありません)。
私はそれをどのように行うことができるかについて大まかな考えを持っていますが、いくつかの場所でこのパターンを実装する方法で .NET フレームワークの内部をのぞいた後、誰かがこれを成功させたかどうかを尋ねて確認するのが賢明だと感じました。特に注意が必要な問題領域。
ありがとう!