将异步编程模型(开始/结束方法)转换为基于事件的异步模型?

发布于 2024-08-10 12:20:19 字数 602 浏览 4 评论 0原文

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

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

有人对如何实现此目标有任何指导(或此类指导的链接)吗?

Let's say I have code that uses the Asynchronous Programming Model, i.e. it provides the following methods as a group which can be used synchronously or asynchronously:

public MethodResult Operation(<method params>);

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

What I want to do is wrap this code with an additional layer that will transform it into the event-driven asynchronous model, like so:

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

Does anyone have any guidance (or links to such guidance) on how to accomplish this?

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

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

发布评论

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

评论(2

为你拒绝所有暧昧 2024-08-17 12:20:19

有关于此的一些想法,请参阅“无痛异步” ;提供的代码使用回调方法,但如果将其放在实例上,事件就会很容易。

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

See "Async without the pain" for some thoughts on this; the code supplied uses a callback approach, but events would be easy enough if you drop it on an instance.

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);
}
柳絮泡泡 2024-08-17 12:20:19

您可以使用 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 主页。有一些视频和示例。

You can the wrapper using AsyncFunc library.

http://asyncfunc.codeplex.com

The code would look like this:

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

Notice that in this approach you don't need to define custom event argument class and event handler delegate. They can be substituted with AsyncFunc generic types:

OperationCompletedEventArgs -> ResultType
OperationCompletedEventHandler -> AsyncFuncCompletedEventHandler<ResultType>

For more advanced scenarios go to AsyncFunc home page. There are some videos and samples.

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