IAsyncResult 接口的正确实现是什么?

发布于 2024-07-21 01:26:06 字数 2456 浏览 4 评论 0 原文

我正在考虑为我创建的类添加一些灵活性,该类建立与远程主机的连接,然后执行信息交换(握手)。 当前的实现提供了一个 Connect 函数,该函数建立连接,然后阻止等待 ManualResetEvent,直到双方完成握手。

下面是调用我的类的示例:

// 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 经典异步模式。 为此,我将提供 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,我需要创建一个实现 IAsyncResult 接口的类,该接口由BeginConnect函数,并分别传递到EndConnect函数中。

现在,我的问题是:在类中实现 IAsyncResult 接口的正确方法是什么?

一个明显的解决方案是创建一个具有 Connect 函数匹配签名的委托,然后异步调用该委托使用 BeginInvoke - EndInvoke 但这不是我正在寻找的(它不是很有效)。

我对如何做到这一点有一个粗略的想法,但是在查看了 .NET 框架内部他们如何在某些地方实现此模式之后,我觉得明智的做法是询问并看看是否有人成功地做到了这一点,如果是,那么有什么需要特别注意的问题领域。

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

疧_╮線 2024-07-28 01:26:06

您可以将调用包装在 IAsyncResult 实现中。 因为我最近一直在研究多线程,所以我在这里发布了它(它也有到该接口的其他实现的链接):

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

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

甚是思念 2024-07-28 01:26:06

您还有许多实现BCL(例如System.Runtime.Remoting.Messaging.AsyncResult) - 使用反射器或参考源来检查它们。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文