gpt4 book ai didi

c# - 为什么 TaskFactory.FromAsync() 重载需要提供状态对象?

转载 作者:太空狗 更新时间:2023-10-30 01:17:26 25 4
gpt4 key购买 nike

详见 TPL and Traditional .NET Framework Asynchronous Programming MSDN 文章和 Stephen Toub 的 Tasks and the APM Pattern博文, TaskFactory.FromAsync() TaskFactory<TResult>.FromAsync() 方法可用于调整符合 APM 模式的 Begin*() 和 End*() API,以便与任务并行库一起使用。

下面我将只讨论 TaskFactory<TResult>.FromAsync()重载,因为我的问题不取决于符合 APM 的 API 是否产生值。

接受 IAsyncResult 的三个重载对象,即:

  • FromAsync(IAsyncResult, Func<IAsyncResult, TResult>)
  • FromAsync(IAsyncResult, Func<IAsyncResult, TResult>, TaskCreationOptions)
  • FromAsync(IAsyncResult, Func<IAsyncResult, TResult>, TaskCreationOptions, TaskScheduler)

据我所知,这些 API 在 Begin*() API 方法除了 AsyncCallback 之外还需要三个以上参数的情况下很有用。和状态object (例如 Too many arguments in BeginXXX for FromAsync ? ),或者当 Begin*() API 不完全符合 APM 模式,因为它不采用状态 object参数(例如 How can I use the AsyncCTP with an TFS APM Method ( Query.Begin / EndQuery )? )。

我不明白的是为什么其余的重载(例如 FromAsync(Func<AsyncCallback, Object, IAsyncResult>, Func<IAsyncResult, TResult>, Object) )都需要一个状态 object待供应。此状态object传递给 Begin*() API,但在 APM 模式中,状态 object供调用者私有(private)使用。所以,什么状态应该无关紧要object传递给 Begin*() API FromAsync() .

上面链接的 MSDN 文章有一个标题为“提供自定义状态数据”的部分,它建议在延续委托(delegate)中捕获任何所需的状态并传递 null对于状态对象 FromAsync() .但是,这并不能解释为什么 FromAsync()方法需要提供状态对象。

为什么是状态object当返回的 Task<TResult> 不可访问时需要传递?

最佳答案

好吧,如果你 follow the source code你可以看到状态确实可以从 Task 实例使用(名字并不奇怪)Task.AsyncState 访问。 :

var task = Task.Factory.FromAsync<TResult>(...);
object state = task.AsyncState

此属性在其他情况下也保存异步操作的状态,例如 Task.Factory.StartNew:

var task = Task.Factory.StartNew(_ => { }, "bar");
Console.WriteLine(task.AsyncState); // prints "bar"

因此,由于状态是可访问的,它应该能够将状态作为参数传递,并且将 API 加倍一次,一次使用状态参数,一次不使用状态参数,这听起来不是更好的选择。尤其是当您可以传入 null 时。

关于c# - 为什么 TaskFactory.FromAsync() 重载需要提供状态对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31764225/

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