“第一个”异步方法是什么样的?

时间:2019-06-26 03:59:03

标签: c# asynchronous async-await

如果async方法“ A”必须在另一个await方法“ B”上async,而方法“ B”必须在另一个{{ 1}}方法“ C”,方法“ C”-“第一个” await方法-看起来如何?我用Google搜索问题“如何创建async方法”。我得到的所有示例都像...方法“ C”内部有一些代码如“ Task.Run()”。我很困惑。 async仅适用于CPU限制,不是吗?但是async方法通常用于I / O绑定操作。有人可以向我解释一下吗?

2 个答案:

答案 0 :(得分:0)

他们中的许多人都包装了带有回调委托的香草异步样式化方法,该方法将在完成时被调用。

请注意,不仅Task,而且所有符合以下规则的类型的实例都可以await编辑:

  • 必须有一个AWAITER GetAwaiter()实例可以调用的await方法(也接受扩展方法),而AWAITER代表与该实例匹配的任何类型。规则。

  • AWAITER必须实现INotifyCompletion来接受应在异步任务完成时调用的回调委托。

  • AWAITER实例必须定义一个bool IsCompleted { get; }才能检查它是否完成。

  • AWAITER实例必须具有定义的RESULT GetResult()方法才能完成await,而RESULT将是await表达式的结果类型如果未返回任何结果,则可能为void

例如:

public static TaskAwaiter<T> GetAwaiter<T>(this T target) => Task.FromResult(target).GetAwaiter();

此方法启用了await的所有类型,这将立即完成,并生成值本身。

var x = await 1;  // int x = 1;

任何符合规则的类型都可以进行await修改,这意味着您可以自己实现它,以在不使用异步方法的情况下手动调用回调委托。

标准API提供了TaskCompletionSource<TResult>,用于将回调异步操作包装到Task,您可能不需要实现自己的等待类型,但是知道await的语法实际上可以使您处理更多案件。

答案 1 :(得分:0)

“ C”方法可能看起来与其他两个类似。所有这些都在内部标记了async关键字和await其他asyhc方法。 “ C”方法只是在等待.NET Framework的本机异步方法,而不是自定义方法。

private static async Task A()
{
    await B();
}

private static async Task B()
{
    await C();
}

private static async Task C()
{
    // Lets await a bunch of stuff just because
    await Task.Delay(1);
    await Task.Yield();
    await Task.FromResult(0).ConfigureAwait(true);
    await Task.CompletedTask.ConfigureAwait(false);
    await Task.Run(() => throw new Exception()).ContinueWith(_ => {});
}