个人站

欢迎来到我的个人站~


Task之旅 - Part 2:AsyncState 和 CreationOptions 属性


目录

太长不看版:

  • TaskAsyncStateCreationOptionsasync 场景下没有用处。

我跳过了上周的文章(因为我忙于网站的重新设计),所以今天买1赠1!😄。

AsyncState

object AsyncState { get; } // 实现了 IAsyncResult.AsyncState

TaskAsyncState 属性实现了 IAsyncResult.AsyncState。这个成员以前很有用,但在现代应用中不怎么有用了。

在异步编程经历它尴尬的青涩时期时,AsyncStateAsynchronous Programming Model(APM) 的一个重要部分。Begin* 方法会接受一个 state 参数,这个参数会被赋给 IAsyncResult.AsyncState。然后,当应用程序代码的回调被调用时,它能够通过访问 AsyncState 的值来确定哪一个异步操作完成了。

IAsyncResult.AsyncState(和其它状态类的参数)现在已经不需要了;lambda 回调能够很容易的以类型安全的方式捕获任意数量的本地变量。我喜欢 lambda 方式,相比单个对象的 state 参数来说,它花费更多、也不那么脆弱而且更加灵活。然而,state参数的方式避免了内存分配,所以有时还是会被用在性能敏感的代码中。

在现代的代码中,Task.AsyncState 成员主要用于 TaskAPM 的互操作。只有在你编写必须存在于一个旧的异步框架里面的 async/await 代码时才需要它(现在已非常罕见)。在那种情形下,你实现 Begin*/End* 方法并且使用一个 Task 实例作为 IAsyncResult 的实现。标准的方法是使用 TaskCompletionSource<T> 创建一个 Task<T>,并把 state 参数传递给 TaskCompletionSource<T> 的构造函数:

public static IAsyncResult BeginOperation(AsyncCallback callback, object state)
{
    var tcs = new TaskCompletionSource<TResult>(state);
    ... // 开始执行操作,然后在操作完毕时完成 "tcs"。(指的是调用 tcs.SetResult 或其它类似方法)
    return tcs.Task;
}

现代代码中并不真的需要读取 AsyncState,它之所以重要是因为它实现了 IAsyncResult.AsyncState

CreationOptions

TaskCreationOptions CreationOptions { get; }

CreationOptions 仅允许你读取用来创建这个任务的创建选项。你可以在使用Task构造函数、Task.Factory.StartNewTaskCompletionSource<T> 创建任务时指定这些选项。我会在后面讲到 Task.Factory.StartNew 时讲这些选项的含义。

尽管如此,一旦任务被创建,几乎没有任何理由再去读取任务的创建选项。只有在你用父/子任务或任务调度做一些有趣的工作时才有需要 – 与异步或并行任务的正常场景毫不相关。

结论

再说一次,这两个成员在真实世界的代码中没有用处。


原文链接:https://blog.stephencleary.com/2014/05/a-tour-of-task-part-2-asyncstate-and-creationoptions.html

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦