我已经阅读了十几篇有关异步/等待的文章,它们都是很棒的读物。但是在所有这些文章中,都没有解决一些困惑/问题。我也在这个论坛上见过(this awesome post) ,但我没有明确的解释,所以我正在寻求您对此事的深入了解。
示例
在下面的Console App示例中,由于未维护同步上下文,因此返回线程ID,即1和5。
(与GUI相似的示例将在同一线程上运行,因为在那里保留了同步上下文。)
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncConcept
{
class Program
{
static void Main(string[] args)
{
AsyncMethod();
Console.WriteLine("Main Thread: " + (int)AppDomain.GetCurrentThreadId());
Console.ReadLine();
}
public static async void AsyncMethod()
{
await Task.Delay(TimeSpan.FromSeconds(5));
Console.WriteLine("AsyncMethod Thread: " + (int)AppDomain.GetCurrentThreadId());
Console.ReadLine();
}
}
}
问题
当我们将await关键字与I / O调用或API调用一起使用时,仅在主线程上发生await操作吗?
a)如果是,主线程(在GUI情况下为UI线程)如何与方法的其余部分同时继续?
b)如果为否,则违反了异步并等待的无线程生成理论。
答案 0 :(得分:1)
当我们将await关键字与I / O调用或API调用一起使用时,仅在主线程上发生await操作吗?
await
发生在运行该方法的任何线程上。在这种情况下,AsyncMethod
在主线程上被调用,await
在主线程上发生。如果AsyncMethod
被UI线程调用,那么await
将会在UI线程上发生。
我认为您正在考虑await
以某种方式“运行”异步操作,但这根本不会发生。我所说的the await
"happening"是await
:
Task.Delay
返回的任务)。如果已经完成,它将继续同步执行该方法。await
(默认情况下)将捕获当前上下文,然后使用该上下文来安排该方法在等待项完成时继续运行。然后await
返回。请注意,如果等待未完成,则该方法返回。在正常情况下,它将返回一个不完整的任务,该任务在async
方法完成时完成;在这种情况下,没有返回类型,因此调用async
方法完成时,调用代码不容易知道。
a)如果是,主线程(在GUI情况下为UI线程)如何与方法的其余部分同时继续?
由于等待未完成,因此await
从方法中返回。该方法的其余部分将在等待完成时运行。