繁体   English   中英

将传统的异步处理程序包装到TPL Task时 <T> 回调和状态会如何?

[英]When wrapping traditional asynchronous handlers to TPL Task<T> what happens to the Callback and State?

此MSDN页面包含以下示例 :目的是包装一个不能在各种Func<T1, T2, T3>重载中表示的APM样式任务。

static Task<String> ReturnTaskFromAsyncResult()
{
    IAsyncResult ar = DoSomethingAsynchronously();     // <-- If this is an APM method, it's a bad example since most APM methods have a parameter for callback and state.
    Task<String> t = Task<string>.Factory.FromAsync(ar, _ =>
        {
            return (string)ar.AsyncState;
        });

    return t;
}

我的问题与函数DoSomethingAsynchronously(); 我见过的大多数APM函数都需要参数callback和state,此示例中没有此参数。

问题: “ DoSomethingAsynchronously”中的回调和状态参数会怎样?

我需要怎么做才能正确调用类似于此的函数? 就我而言,我试图像这样包装Azure Table调用

    Task CreateAsync(CloudTable tbl, CancellationToken token, object state)
    {
        ICancellableAsyncResult result = tbl.BeginCreate(null, state);  // Incorrect
        token.Register((o) => result.Cancel(), state);

        Task<bool> t = Task.Factory.FromAsync(result, _ =>
        {
            return (bool)result.AsyncState;
        });

        return t;
    }
    Task<bool> ExistsAsync(CloudTable tbl, CancellationToken token, object state)
    {
        ICancellableAsyncResult result = tbl.BeginExists(null, state);  // Incorrect
        token.Register((o) => result.Cancel(), state);

        Task<bool>  t = Task.Factory.FromAsync(result, _ =>
        {
            return (bool)result.AsyncState;
        });

        return t;
    }

我认为您误解了state参数的用途。 它在那里供您使用 :当您在其中传递对象时,可以通过访问AsyncState检索它。 (并且类似地在CancellationToken.Register() state 。)在这种情况下,您不需要任何state ,因此您应该在其中传递null 这也意味着您没有理由要创建的方法具有state参数。

callback参数用于异步操作完成时要执行的代码。 您不需要的FromAsync()重载不使用此方法,因此您也应该在其中传递null

似乎您也对放在endMethod委托中的内容感到困惑。 顾名思义,您应该在其中调用EndXxx()方法(在您的情况下为EndCreate()EndExists() )。 如果整个操作都返回了某些内容,则它实际上将由end方法返回,因此您应该从委托中返回它。 然后,它将作为创建的Task的结果可用。 您还可以在委托中执行一些清理。 在您的情况下,我认为将取消注册在那里处置是有意义的,因为不再需要取消注册。

因此,您的代码应类似于:

Task CreateAsync(CloudTable tbl, CancellationToken token)
{
    ICancellableAsyncResult result = tbl.BeginCreate(null, null);
    var cancellationRegistration = token.Register(result.Cancel);

    return Task.Factory.FromAsync(result, ar =>
    {
        cancellationRegistration.Dispose();
        tbl.EndCreate(ar);
    });
}

Task<bool> ExistsAsync(CloudTable tbl, CancellationToken token)
{
    ICancellableAsyncResult result = tbl.BeginExists(null, null);
    var cancellationRegistration = token.Register(result.Cancel);

    return Task.Factory.FromAsync(result, ar =>
    {
        cancellationRegistration.Dispose();
        return tbl.EndExists(ar);
    });
}

有关此主题的更多信息,请查看Stephen Toub的“ 任务”和“ APM模式”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM