【问题标题】:Converting Asynchronous Programming Model (Begin/End methods) into event-based asynchronous model?将异步编程模型(开始/结束方法)转换为基于事件的异步模型?
【发布时间】:2017-12-29 20:03:15
【问题描述】:

假设我有使用异步编程模型的代码,即它提供以下方法作为一组可以同步或异步使用:

public MethodResult Operation(<method params>);

public IAsyncResult BeginOperation(<method params>, AsyncCallback callback, object state);
public MethodResult EndOperation(IAsyncResult ar);

我想要做的是用一个额外的层来包装这段代码,它将它转换为事件驱动的异步模型,如下所示:

public void OperationAsync(<method params>);
public event OperationCompletedEventHandler OperationCompleted;
public delegate void OperationCompletedEventHandler(object sender, OperationCompletedEventArgs e);

是否有人对如何完成此操作有任何指导(或此类指导的链接)?

【问题讨论】:

    标签: c# .net asynchronous iasyncresult


    【解决方案1】:

    请参阅"Async without the pain" 了解有关此的一些想法;提供的代码使用回调方法,但如果将其放在实例上,事件会很容易。

    public static void RunAsync<T>(
        Func<AsyncCallback, object, IAsyncResult> begin,
        Func<IAsyncResult, T> end,
        Action<Func<T>> callback) {
        begin(ar => {
            T result;
            try {
                result = end(ar); // ensure end called
                callback(() => result);
            } catch (Exception ex) {
                callback(() => { throw ex; });
            }
        }, null);
    }
    

    【讨论】:

    • (我会添加一个示例,但火车超出了覆盖范围)
    • 有趣 - 这种代码风格看起来非常类似于任务并行库。
    • 简短地回到接收...至少在签名中,F# 的工作原理并不遥远,所以我预计会有相似之处。
    【解决方案2】:

    您可以使用 AsyncFunc 库进行包装。

    http://asyncfunc.codeplex.com

    代码如下所示:

    public class Original
    {
        public ResultType Operation(ParamType param){...}
        public IAsyncResult BeginOperation(ParamType param, AsyncCallback callback, object state){...}
        public ResultType EndOperation(IAsyncResult ar){...}
    }
    
    public class Wrapper
    {
        private AsyncFunc<ParamType, ResultType> _operation;
        private Original _original;
    
        public Wrapper(Original original)
        {
            _original = original;
            _operation = AsyncFunc<ParamType, ResultType>(_original.Operation);
        }
    
        public ResultType Operation(ParamType param)
        {
            return _original.Operation(param);
        }
    
        public void OperationAsync(ParamType param)
        {
            _operation.InvokeAsync(param)
        }
    
        public event AsyncFuncCompletedEventHandler<ResultType> OperationCompleted      
          {
            add { _operation.Completed += value; }
            remove { _operation.Completed -= value; }
        }
    }
    

    请注意,在这种方法中,您不需要定义自定义事件参数类和事件处理程序委托。它们可以用 AsyncFunc 泛型类型代替:

    OperationCompletedEventArgs -> ResultType
    OperationCompletedEventHandler -> AsyncFuncCompletedEventHandler<ResultType>
    

    更多高级场景请访问 AsyncFunc 主页。有一些视频和示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-13
      • 1970-01-01
      相关资源
      最近更新 更多