asnyc和await是什么?
异步编程是一种编程范式,C#中的异步编程可以通过Thread,TheadPool,Task,async/await等来实现。
await能等待什么?
不能等待同步代码,只能等待Task或异步方法,且异步方法必须有返回值,
async/await的出现:
C#5(.NET4.5)引入的语法糖
C#7.1,Main入口也可以
C#8.0,可以使用异步流await,foreach可以释放对象await using
asnyc:
async
是一个修饰符,用于声明一个方法、lambda表达式或者匿名方法为异步的。
异步方法通常用于执行可能需要很长时间的操作,比如I/O操作(文件读写、网络请求等),而不会阻塞当前线程。
使用 async
修饰的方法必须有返回值,可以是 Task
, Task<T>
或者 void
(在C# 7.3及以后版本中,void
异步方法是不推荐的,因为它不能使用 await
)。
await:
await
是一个操作符,用于等待一个异步操作完成,而不会阻塞当前线程。
await
只能在标记为 async
的方法内部使用。
当执行到 await
表达式时,控制权会返回给调用者,直到被 await
的任务完成。当任务完成后,执行会从 await
表达式之后的代码继续进行。
public async Task<string> GetDataAsync()
{
// 模拟异步操作
await Task.Delay(1000); // 等待1秒
return "Data";
}
public async void UseAsyncMethod()
{
string data = await GetDataAsync(); // 使用await等待GetDataAsync完成
Console.WriteLine(data);
}
async/await优点
- 代码可读性:使用
async
和await
可以使异步代码看起来和同步代码非常相似,提高了代码的可读性。 - 避免回调地狱:传统的异步编程通常使用回调函数,这可能导致代码结构复杂,难以理解和维护。
async
和await
避免了这种情况。 - 更好的错误处理:异步方法可以像同步方法一样使用
try-catch
块来处理异常。 - 提高性能:通过异步编程,应用程序可以在等待I/O操作完成时继续执行其他任务,从而提高应用程序的响应性和吞吐量。
- 简化异步编程:开发者可以编写更少的代码来实现异步逻辑,因为
async
和await
抽象了很多底层的复杂性。
总结:1.既要有顺序,又要不阻塞,降低了编程难度 2.以同步编程的方式来写异步
定义异步方法、再方法返回值前 添加async关键字
public void Sayhello1()
{
Console.WriteLine("同步的方法");
}
public async void Sayhello2()
{
Console.WriteLine("异步方法");
}
单独使用async,不使用await,警告缺少 await运算符,不是真正的异步方法
但Await不能等待同步代码,只能等待task或异步方法
await必须等待结果,没结果不能等待(无法等待void),要求:Task或其它的异步方法必须有返回值
正确的
Await直接等待结果不行,结果不是task或异步方法
单独使用await,不使用async,报错。
记住原则:有async地方必须有await,反之也是。
带返回值的异步方法可以使用await等待。
public async Task Sayhello3(string a)
{
//await Console.WriteLine("同步的方法");
Task<string> task = new Task<string>(() =>
{
return "hello";
});
await task;
}
private async void button1_Click(object sender, EventArgs e)
{
await Sayhello3("xixi");
}
异步方法带返回值的:必须返回Task,Task<T>
public async Task Sayhello3(string a)
{
Task<string> task = new Task<string>(() =>
{
return "hello";
});
await task;
}
调用异步方法,await不会阻塞
private async void button1_Click(object sender, EventArgs e)
{
Sayhello3("xixi2");//直接调用不建议
await Sayhello3("xixi");//Wait()方法会阻塞,await不会阻塞
}
异步方法不带返回值,真正的异步方法
异步方法没有返回值,不可以等待,不等待时,异步执行。
private void button1_Click(object sender, EventArgs e)
{
调用
Sayhello4();
}
private async void Sayhello4()
{
Task t = Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine("hello world");
});
await t;
}
规律:返回Task的不需要return,只需要await。
返回Task<T>的必须有await和return。
调用