C#异步编程学习笔记之-async和await

一、异步方法介绍(async和await):
如果使用async修饰符将某种方法指定为异步方法,即启用以下两种功能。
1、标记的异步方法可以使用await来指定暂停点。await运算符通知编译器异步方法:在等待的异步过程完成后才能继续通过该点。 同时,控制返回至异步方法的调用方。
   异步方法在await表达式执行时暂停并不构成方法退出,只会导致 finally 代码块不运行。
2、标记的异步方法本身可以通过调用它的方法等待。

注意:
★ 异步方法通常包含await运算符的一个或多个实例,但缺少await表达式也不会导致生成编译器错误(编译器将为此类方法发布一个警告),如:

如果异步方法未使用await运算符标记暂停点,那么异步方法会作为同步方法执行,即使有async修饰符,也不例外。

二、异步方法示例:
使用async关键字定义的异步方法简称为“异步方法”,如:

async Task<int> AccessTheWebAsync()  
{   
    HttpClient client = new HttpClient();  
    //耗时处理,需要异步执行
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");  

    //这里是不需要异步执行的内容  
    DoIndependentWork();  
    
    //使用await标记为异步获取结果,并把AccessTheWebAsync方法挂起,控制返回至异步方法的调用方。
    string urlContents = await getStringTask;  

    //直到异步结果返回,才执行这里
    return urlContents.Length;  
}  

如果 AccessTheWebAsync 在调用 GetStringAsync 和等待其完成期间不能进行任何工作,则你可以通过在下面的单个语句中调用和等待来简化代码:

string urlContents = await client.GetStringAsync();  

意思是,一个异步方法内部可以用await标记多个点。

三、异步方法特征:
1、方法签名包含 async 修饰符。
2、按照约定,异步方法的名称以“Async”后缀结尾。
3、返回类型为下列类型之一:
   ※ 如果你的方法有操作数为 TResult 类型的返回语句,则为 Task<TResult>。
   ※ 如果你的方法没有返回语句或具有没有操作数的返回语句,则为 Task。
   ※ void:如果要编写异步事件处理程序。
   ※ 包含 GetAwaiter 方法的其他任何类型(自 C# 7.0 起)。
4、方法通常包含至少一个 await 表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成方法才能继续。 同时,将方法挂起,并且控制返回到方法的调用方。
5、异步方法无法声明 in、ref 或 out 参数,但可以调用包含此类参数的方法。 同样,异步方法无法通过引用返回值,但可以调用包含 ref 返回值的方法。

四、异步方法的运行机制:

五、返回类型和参数:
异步方法通常返回 Task 或 Task<TResult>。 在异步方法中,await 运算符应用于通过调用另一个异步方法返回的任务。
如果方法包含指定 TResult 类型操作数的 return 语句,将 Task<TResult> 指定为返回类型。
如果方法不含任何 return 语句或包含不返回操作数的 return 语句,将 Task 用作返回类型。

下面的示例演示如何声明并调用可返回 Task<TResult> 或 Task 的方法:

//声明返回类型为Task<TResult>,即TResult
async Task<int> TaskOfTResult_MethodAsync()  
{  
    int hours;  
    // . . .  
    //返回值为int类型  
    return hours;  
}  

//调用TaskOfTResult_MethodAsync  
Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();  
//标记为异步返回
int intResult = await returnedTaskTResult;  
//另一种方式 
int intResult = await TaskOfTResult_MethodAsync();  

 

//声明返回类型为Task,即void
async Task Task_MethodAsync()  
{  
    // . . .  
}  

//调用Task_MethodAsync  
Task returnedTask = Task_MethodAsync(); 
//标记为异步返回
await returnedTask;  
//另一种方式   
await Task_MethodAsync(); 

 

来源:
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/index

posted @ 2018-08-17 11:53  skybirdzw  阅读(343)  评论(0编辑  收藏  举报