首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >显式实现IAsyncResult

显式实现IAsyncResult
EN

Stack Overflow用户
提问于 2009-01-01 23:04:52
回答 2查看 9.9K关注 0票数 6

我通常对部分实现接口持谨慎态度。然而,IAsyncResult是一个特例,因为它支持几种完全不同的使用模式。与仅仅调用EndInvoke、使用AsyncWaitHandle或轮询IsCompleted (讨厌)相比,您经常使用/看到使用过的AsyncState/AsyncCallback模式吗?

相关问题:Detecting that a ThreadPool WorkItem has completed/waiting for completion

考虑这个类(非常近似,需要锁定):

代码语言:javascript
复制
public class Concurrent<T> {
    private ManualResetEvent _resetEvent;
    private T _result;

    public Concurrent(Func<T> f) {
        ThreadPool.QueueUserWorkItem(_ => {
                                         _result = f();
                                         IsCompleted = true;
                                         if (_resetEvent != null)
                                             _resetEvent.Set();
                                     });
    }

    public WaitHandle WaitHandle {
        get {
            if (_resetEvent == null)
                _resetEvent = new ManualResetEvent(IsCompleted);
            return _resetEvent;
        }

    public bool IsCompleted {get; private set;}
    ...

它有WaitHandle (懒惰地创建,就像IAsyncResult文档中描述的那样)和IsCompleted,但我没有看到AsyncState的合理实现({return null;}?)。那么它实现IAsyncResult有意义吗?请注意,并行扩展库中的Task确实实现了IAsyncResult,但只有IsCompleted是隐式实现的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-01-02 00:04:51

  • 在我的经验中,只调用EndInvoke而不等待或者没有首先被回调是很少有用的
  • 仅仅提供回调有时是不够的,因为你的客户端可能想要一次等待多个操作(WaitAny,WaitAll)
  • 我从来没有轮询过IsCompleted,讨厌!因此,您可以保留IsCompleted的实现,但它太简单了,似乎不值得让您的客户感到惊讶。

因此,异步可调用方法的合理实现应该真正提供一个完全实现的IAsyncResult。

顺便说一句,您通常不需要自己实现IAsyncResult,只需返回Delegate.BeginInvoke返回的内容即可。有关示例,请参阅System.IO.Stream.BeginRead的实现。

票数 2
EN

Stack Overflow用户

发布于 2009-01-02 02:02:37

看起来你有几个问题。让我们分别处理它们

创建WaitHandle惰性

是的,这是最正确的方法。你应该以一种线程安全的方式来做这件事,但是懒惰是一种方式。

不过,诀窍在于丢弃WaitHandle。WaitHandle是IDisposable的基础,必须及时处理。IAsycResult的文档不包括这种情况。最好的方法是在EndInvoke中实现。BeginInvoke的文档明确指出,对于每个BeginInvoke,都必须有相应的EndInvoke (或BeginRead/EndRead)。这是处理WaitHandle的最佳位置。

应该如何实现AsyncState?

如果您查看返回状态的标准BCL,它们中的大多数都带有IAsyncResult参数。这通常是从AsyncState返回的值(有关示例,请参阅Socket API)。对于任何返回IAsyncResult的BeginInvoke风格的API,最好包含一个类型化为object的状态变量。不是必须的,但这是很好的实践。

在没有状态变量的情况下,返回null是可以接受的。

IsCompleted接口

这将高度依赖于创建IAsyncResult的实现。但是,是的,你应该实现它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/405647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档