详见TPL and Traditional .NET Framework Asynchronous Programming MSDN文章和Stephen Toub的Tasks and the APM Pattern博客文章,TaskFactory.FromAsync()
和TaskFactory<TResult>.FromAsync()
方法可用于调整Begin *( )和End *()API符合APM模式,用于任务并行库。
下面我将仅讨论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
供调用方私人使用。因此,object
通过Begin*()
API传递状态FromAsync()
并不重要。
上面链接的MSDN文章标题为&#34;提供自定义状态数据&#34;建议在延续委托中捕获任何所需的状态,并将状态对象的null
传递给FromAsync()
。但是,这并不能解释为什么FromAsync()
方法需要给出状态对象。
为什么状态object
在返回的Task<TResult>
无法访问时需要传递?
答案 0 :(得分:4)
好吧,如果你follow the source code,你可以看到确实可以使用Task
var task = Task.Factory.FromAsync<TResult>(...);
object state = task.AsyncState
实例访问状态Task.AsyncState
:
Task.Factory.StartNew
此属性同时保存异步操作的状态,如var task = Task.Factory.StartNew(_ => { }, "bar");
Console.WriteLine(task.AsyncState); // prints "bar"
:
null
因此,由于状态是可访问的,因此期望能够将状态作为参数传递,并使用状态参数将API加倍一次,并且一次不会听起来像是更好的选项。特别是当你可以传递os.system(''.join(["loimpress ",filename]))
时。