C# 中的 Async 和 Await 关键字是异步编程的核心。 通过这两个关键字,可以使用 .NET Framework、.NET Core 或 Windows 运行时中的资源,轻松创建异步方法(几乎与创建同步方法一样轻松)。 使用 async
关键字定义的异步方法简称为“异步方法”。
下面的示例演示了一种异步方法。 你应对代码中的几乎所有内容都很熟悉。
可从 C# 中使用 Async 和 Await 的异步编程中找到可供下载的完整 Windows Presentation Foundation (WPF) 示例。
C#复制
public async Task<int> GetUrlContentLengthAsync()
{
using var client = new HttpClient();
Task<string> getStringTask =
client.GetStringAsync("https://learn.microsoft.com/dotnet");
DoIndependentWork();
string contents = await getStringTask;
return contents.Length;
}
void DoIndependentWork()
{
Console.WriteLine("Working...");
}
可以从前面的示例中了解几种做法。 从方法签名开始。 它包含 async
修饰符。 返回类型为 Task<int>
(有关更多选项,请参阅“返回类型”部分)。 方法名称以 Async
结尾。 在方法的主体中,GetStringAsync
返回 Task<string>
。 这意味着在 await
任务时,将获得 string
(contents
)。 在等待任务之前,可以通过 GetStringAsync
执行不依赖于 string
的工作。
密切注意 await
运算符。 它会暂停 GetUrlContentLengthAsync
:
- 在
getStringTask
完成之前,GetUrlContentLengthAsync
无法继续。 - 同时,控件返回至
GetUrlContentLengthAsync
的调用方。 - 当
getStringTask
完成时,控件将在此处继续。 - 然后,
await
运算符会从getStringTask
检索string
结果。
return 语句指定整数结果。 任何等待 GetUrlContentLengthAsync
的方法都会检索长度值。
如果 GetUrlContentLengthAsync
在调用 GetStringAsync
和等待其完成期间不能进行任何工作,则你可以通过在下面的单个语句中调用和等待来简化代码。
C#复制
string contents = await client.GetStringAsync("https://learn.microsoft.com/dotnet");
以下特征总结了使上一个示例成为异步方法的原因:
- 方法签名包含
async
修饰符。 - 按照约定,异步方法的名称以“Async”后缀结尾。
- 返回类型为下列类型之一:
- 如果你的方法有操作数为
TResult
类型的返回语句,则为 Task<TResult>。 - 如果你的方法没有返回语句或具有没有操作数的返回语句,则为 Task。
void
:如果要编写异步事件处理程序。- 具有
GetAwaiter
方法的任何其他类型。
- 如果你的方法有操作数为
- 方法通常包含至少一个
await
表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成方法才能继续。 同时,将方法挂起,并且控件返回到方法的调用方。 本主题的下一节将解释悬挂点发生的情况。
在异步方法中,可使用提供的关键字和类型来指示需要完成的操作,且编译器会完成其余操作,其中包括持续跟踪控件以挂起方法返回等待点时发生的情况。 一些常规流程(例如,循环和异常处理)在传统异步代码中处理起来可能很困难。 在异步方法中,元素的编写频率与同步解决方案相同且此问题得到解决。
若要详细了解旧版 .NET Framework 中的异步性,请参阅 TPL 和传统 .NET Framework 异步编程。异步方法易于编写
C# 中的 Async 和 Await 关键字是异步编程的核心。 通过这两个关键字,可以使用 .NET Framework、.NET Core 或 Windows 运行时中的资源,轻松创建异步方法(几乎与创建同步方法一样轻松)。 使用 async
关键字定义的异步方法简称为“异步方法”。
下面的示例演示了一种异步方法。 你应对代码中的几乎所有内容都很熟悉。
可从 C# 中使用 Async 和 Await 的异步编程中找到可供下载的完整 Windows Presentation Foundation (WPF) 示例。
C#复制
public async Task<int> GetUrlContentLengthAsync()
{
using var client = new HttpClient();
Task<string> getStringTask =
client.GetStringAsync("https://learn.microsoft.com/dotnet");
DoIndependentWork();
string contents = await getStringTask;
return contents.Length;
}
void DoIndependentWork()
{
Console.WriteLine("Working...");
}
可以从前面的示例中了解几种做法。 从方法签名开始。 它包含 async
修饰符。 返回类型为 Task<int>
(有关更多选项,请参阅“返回类型”部分)。 方法名称以 Async
结尾。 在方法的主体中,GetStringAsync
返回 Task<string>
。 这意味着在 await
任务时,将获得 string
(contents
)。 在等待任务之前,可以通过 GetStringAsync
执行不依赖于 string
的工作。
密切注意 await
运算符。 它会暂停 GetUrlContentLengthAsync
:
- 在
getStringTask
完成之前,GetUrlContentLengthAsync
无法继续。 - 同时,控件返回至
GetUrlContentLengthAsync
的调用方。 - 当
getStringTask
完成时,控件将在此处继续。 - 然后,
await
运算符会从getStringTask
检索string
结果。
return 语句指定整数结果。 任何等待 GetUrlContentLengthAsync
的方法都会检索长度值。
如果 GetUrlContentLengthAsync
在调用 GetStringAsync
和等待其完成期间不能进行任何工作,则你可以通过在下面的单个语句中调用和等待来简化代码。
C#复制
string contents = await client.GetStringAsync("https://learn.microsoft.com/dotnet");
以下特征总结了使上一个示例成为异步方法的原因:
- 方法签名包含
async
修饰符。 - 按照约定,异步方法的名称以“Async”后缀结尾。
- 返回类型为下列类型之一:
- 如果你的方法有操作数为
TResult
类型的返回语句,则为 Task<TResult>。 - 如果你的方法没有返回语句或具有没有操作数的返回语句,则为 Task。
void
:如果要编写异步事件处理程序。- 具有
GetAwaiter
方法的任何其他类型。
- 如果你的方法有操作数为
- 方法通常包含至少一个
await
表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成方法才能继续。 同时,将方法挂起,并且控件返回到方法的调用方。 本主题的下一节将解释悬挂点发生的情况。
在异步方法中,可使用提供的关键字和类型来指示需要完成的操作,且编译器会完成其余操作,其中包括持续跟踪控件以挂起方法返回等待点时发生的情况。 一些常规流程(例如,循环和异常处理)在传统异步代码中处理起来可能很困难。 在异步方法中,元素的编写频率与同步解决方案相同且此问题得到解决。
若要详细了解旧版 .NET Framework 中的异步性,请参阅 TPL 和传统 .NET Framework 异步编程。