gpt4 book ai didi

c# - 将传统异步处理程序包装到 TPL Task 时,回调和状态会发生什么?

转载 作者:太空宇宙 更新时间:2023-11-03 18:11:49 25 4
gpt4 key购买 nike

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

最佳答案

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

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

您似乎也对在 endMethod 委托(delegate)中放入什么内容感到困惑。顾名思义,您应该调用其中的 EndXxx() 方法(在您的情况下,即 EndCreate()EndExists()) 。如果整个操作返回一些东西,它实际上会由 end 方法返回,所以你应该从委托(delegate)返回它。然后它将作为创建的任务的结果可用。您还可以在委托(delegate)中执行一些清理操作。就您而言,我认为在那里处理取消注册是有意义的,因为不再需要它。

所以,您的代码应该类似于:

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

有关此主题的更多信息,请查看 Tasks and the APM Pattern来自斯蒂芬·托布。

关于c# - 将传统异步处理程序包装到 TPL Task<T> 时,回调和状态会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13427417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com