
关系图中的数值对应于以下步骤。
-
事件处理程序调用并等待
AccessTheWebAsync异步方法。 -
AccessTheWebAsync可创建HttpClient实例并调用GetStringAsync
异步方法以下载网站内容作为字符串。 -
GetStringAsync中发生了某种情况,该情况挂起了它的进程。 可能必须等待网站下载或一些其他阻止活动。
为避免阻塞资源,GetStringAsync会将控制权出让给其调用方AccessTheWebAsync。GetStringAsync返回Task<TResult>,其中TResult为字符串,并且AccessTheWebAsync将任务分配给getStringTask变量。 该任务表示调用GetStringAsync的正在进行的进程,其中承诺当工作完成时产生实际字符串值。 -
由于尚未等待
getStringTask,因此,AccessTheWebAsync可以继续执行不依赖于GetStringAsync得出的最终结果的其他工作。 该任务由对同步方法DoIndependentWork的调用表示。 -
DoIndependentWork是完成其工作并返回其调用方的同步方法。 -
AccessTheWebAsync已运行完可以不受getStringTask结果影响的工作任务。
接下来,AccessTheWebAsync需要计算并返回该下载字符串的长度,但该方法仅在具有字符串时才能计算该值。因此,
AccessTheWebAsync使用一个await运算符来挂起其进度,并把控制权交给调用AccessTheWebAsync的方法。AccessTheWebAsync将Task<int>返回给调用方。 该任务表示对产生下载字符串长度的整数结果的一个承诺。如果
GetStringAsync(因此getStringTask)在AccessTheWebAsync等待前完成,则控制会保留在AccessTheWebAsync中。 如果异步调用过程 (getStringTask) 已完成,并且AccessTheWebSync不必等待最终结果,则挂起然后返回到AccessTheWebAsync将造成成本浪费。在调用方内部(此示例中的事件处理程序),处理模式将继续。 在等待结果前,调用方可以开展不依赖于
AccessTheWebAsync结果的其他工作,否则就需等待片刻。 事件处理程序等待AccessTheWebAsync,而AccessTheWebAsync等待GetStringAsync。 -
GetStringAsync完成并生成一个字符串结果。 字符串结果不是通过按你预期的方式调用GetStringAsync所返回的。(记住,该方法已返回步骤 3 中的一个任务)。相反,字符串结果存储在表示getStringTask方法完成的任务中。await运算符从getStringTask中检索结果。 赋值语句将检索到的结果赋给urlContents。 -
当
AccessTheWebAsync具有字符串结果时,该方法可以计算字符串长度。 然后,AccessTheWebAsync工作也将完成,并且等待事件处理程序可继续使用。 在此主题结尾处的完整示例中,可确认事件处理程序检索并打印长度结果的值。
如果你不熟悉异步编程,请花 1 分钟时间考虑同步行为和异步行为之间的差异。 当其工作完成时(第 5 步)会返回一个同步方法,但当其工作挂起时(第 3 步和第 6 步),异步方法会返回一个任务值。
在异步方法最终完成其工作时,任务会标记为已完成,而结果(如果有)将存储在任务中。
本文介绍了异步编程中事件处理程序调用异步方法的过程。异步方法在执行中可能挂起进程,为避免阻塞资源会出让控制权。任务表示正在进行的进程,承诺完成时产生结果。还说明了异步与同步行为差异,异步方法工作挂起时返回任务值,完成后任务标记已完成,结果存于任务中。
2026

被折叠的 条评论
为什么被折叠?



