13

私が作成したクラスに柔軟性を追加して、リモート ホストへの接続を確立し、情報交換 (ハンドシェイク) を実行することを検討しています。現在の実装は、接続を確立し、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 フレームワークの内部をのぞいた後、誰かがこれを成功させたかどうかを尋ねて確認するのが賢明だと感じました。特に注意が必要な問題領域。

ありがとう!

4

2 に答える 2

1

また、BCL には多くの実装があります (例: System.Runtime.Remoting.Messaging.AsyncResult)。それらをチェックするには、リフレクターまたは参照ソースを使用してください。

于 2012-05-16T11:51:09.693 に答える
1

IAsyncResult 実装で呼び出しをラップできます。最近マルチスレッドに注目しているので、ここに投稿しました (インターフェースの他の実装へのリンクもあります)。

http://msmvps.com/blogs/luisabreu/archive/2009/06/15/multithreading-implementing-the-iasyncresult-interface.aspx

于 2009-06-15T10:51:20.123 に答える