What is a proper implementation of the IAsyncResul

2019-04-04 18:43发布

问题:

I'm looking into adding some flexibility to a class that I've created which establishes a connection to a remote host and then performs an exchange of information (a handshake). The current implementation provides a Connect function which establishes the connection and then blocks waiting on a ManualResetEvent untill the two parties have completed the handshake.

Here's an example of what calling my class looks like:

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

}

..and here's an oversimplified high-level view of what the class does internally:

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

I'm looking into implementing the .NET Classic Async Pattern for this class. In doing so, I would provide BeginConnect and EndConnect functions, and allow the users of the class to write code like this:

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

In order to be able to provide this API I need to create a class that implements the IAsyncResult interface to be returned by the BeginConnect function, and to be passed into the EndConnect function respectively.

Now, my question is: What is a proper way to implement the IAsyncResult interface in a class?

One obvious solution would be to create a delegate with a matching signature for the Connect function and then invoke that delegate asynchronously using BeginInvoke - EndInvoke but that is not what I'm looking for (it's not very efficient).

I have a rough idea of how I could do it but after peeking inside the .NET framework at how they implement this pattern in some places I felt it would be wise to ask and see if anybody has done this successfully and if so what are the problem areas to pay special attention to.

Thanks!

回答1:

You can wrap the invocation in the IAsyncResult implementation. Since I've been looking at multithreading lately, I've posted about it here (it has links to other implementations of the interface too):

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



回答2:

  • Jeffery Richter (MSDN Magazine)
  • Microsoft's WCF Samples
  • Niko Schuessler (MS employee)
  • Google "IAsyncResult Implementation" for more...

You also have many implementations in the BCL (e.g. System.Runtime.Remoting.Messaging.AsyncResult) - use reflector or the reference source to check them out.