This MSDN page has the following example:目的是包装一个无法在各种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函数都需要参数回调和状态,这在本示例中是缺失的。
问题:“DoSomethingAsynchronously”中的回调和状态参数会发生什么
如何正确调用与此类似的功能,我需要做什么?在我的情况下,我试图像这样包装Azure表调用
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;
}
答案 0 :(得分:8)
我认为您误解了state
参数的用途。它就在那里你:当你在那里传递一个对象时,你可以通过访问AsyncState
来检索它。 (以及state
中的CancellationToken.Register()
类似。)在这种情况下,您不需要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的Tasks and the APM Pattern。