明确地实现IAsyncResult

Ale*_*nov 6 c# concurrency asynchronous iasyncresult

我一般都对部分实现接口持谨慎态度.但是,IAsyncResult它有点特殊情况,因为它支持几种截然不同的使用模式.你经常使用/看看使用AsyncState/ AsyncCallbackpattern,而不是只是调用EndInvoke,使用AsyncWaitHandle或轮询IsCompleted(yuck)?

相关问题:检测ThreadPool WorkItem是否已完成/等待完成.

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

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;}
    ...
Run Code Online (Sandbox Code Playgroud)

WaitHandle(懒惰创建,正如IAsyncResult文档中所述)IsCompleted,但我没有看到AsyncState({return null;}?)的合理实现.那么实施它是否有意义IAsyncResult?请注意,Task在Parallel Extensions库中确实实现了IAsyncResult,但只是IsCompleted隐式实现.

小智 2

  • 根据我的经验,仅调用 EndInvoke 而不等待或先被回调很少有用
  • 仅提供回调有时是不够的,因为您的客户端可能希望一次等待多个操作(WaitAny、WaitAll)
  • 我从来没有投票过 IsCompleted,确实很恶心!因此,您可以保存 IsCompleted 的实现,但它太简单了,似乎不值得让您的客户感到惊讶。

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

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