我刚刚介绍了这个概念,如果答案很简单,那么道歉。
我理解async
只是一个标志,表示方法中有await
,并且当异步方法正在执行其工作时,控件将返回调用方。我的理解是,假设调用堆栈中的某个地方没有等待异步方法,而不是至少立即(即在执行异步方法时完成其他一些工作),这是有用的。
但是,await
似乎仅适用于async
方法,而await
方法内部必须包含{{1}}。这创造了无穷无尽的呼叫链。它必须在某处结束,等待应用于非异步方法。但在哪里?
答案 0 :(得分:4)
然而,await似乎只适用于异步方法,而异步方法又必须等待内部。
从技术上讲,await
不适用于方法。发生的方法是调用该方法并返回一些内容(例如Task
),然后await
将应用于该任务。
所以,误解在于:await
适用于等待物(例如,任务),而不是方法。
它必须以某种方式结束,等待应用于非异步方法。
烨。任何方法都可以返回Task
(或任何等待的),无论是async
还是async
。一个方法可以使用TaskFactory.FromAsync
来构造它的任务(大多数方法我们写这样做),但它也可以直接构建一个。通常,低级异步方法使用TaskCompletionSource<T>
或srand()
来创建他们返回的任务。
答案 1 :(得分:-1)
它最终会出现在您正在使用的最高层以及您不想阻止的层上。我们假设你有一个Winforms应用程序。这里的所有方法都会在某种情况下结束,这将是异步链的结束。
例如:
private async Task DoSomethingAsync()
{
await DbClass.GetSomeItemsFromDbAsync();
}
public partial class MyForm : Form
{
private async void btButton_Click(object sender, EventArgs e)
{
await DoSomethingAsync();
}
}
如果您在示例中看到,我们有一个异步方法。在Button的Click-Event中调用此方法。因此,事件监听器被标记为异步,但不能从其他任何东西调用。在这里,您离开您的链并到达终点。表格不会阻止,这就是我们想要实现的目标。
如果您考虑使用GUI,所有方法都会以事件结束,因为整个程序都是事件驱动的。在Console App中,Endpoint将是Main-Method。在那里你不会将返回类型从void更改为Task,这将停止你的异步链,因为无法等待void。
我希望这可以帮助您理解链条。