当前位置:首页 > 技能相关 > .NET > 正文内容

.NET Async与Await 异步编程

admin2年前 (2023-02-20).NET3220 修订时间:2023-02-21 08:44:29

前言

当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法

NET 4.0 在 ThreadPool 的基础上推出了 Task 类,推荐使用Task来执行异步任务;
NET 5.0 推出了 async/await,让异步编程更为方便;

C# 中的 Async  Await 关键字是异步编程的核心。使用这两个关键字可以轻松创建异步方法。

异步编程

并发的一种形式,它采用furture模式或回调(callback)机制,以避免产生不必要的线程。.Net中future的类型有 Task 和 Task<Result> 。

static async Task Main(string[] args)
{
    await File.WriteAllTextAsync(@"D:\vs2019\netcode\AsyncandAwait\1.txt","hello world!!!");
    Console.Read();
}

异步编程的核心理念是异步操作:

1、启动了的操作将会在一段时间后完成。

2、这个操作正在执行时,但不会阻塞原来的线程。

3、启动了这个操作的线程后,可以继续执行其它任务。

4、当操作完成时,它会通知它的future,或者调用回调函数,以便让程序知道操作已经结束。

异步的好处

1、对于面向终端用户的GUI程序,异步可以提高响应能力。

2、对于服务器应用:异步编程实现了可扩展。

3、服务器可以利用线程池填满其可扩展性,使用异步编程后,可扩展性通常可以提供一个数量级,可以最大程度的压榨服务器性能,提高处理能力。

Async

使用 async 修饰符可以将方法、lambda表达式或匿名方法指定为异步。async 的主要目的是使方法内的await关键字生效。

//等待异步完成再执行后边的操作,但是整个方法不会阻塞
var result = await DoSomethingAsync();
output.Result = result;

Await

async 标记的异步方法,可以使用 await 来指定暂定点。

执行逻辑:

1、async 方法在开始时以同步的方式执行。

2、在 async 方法内部,await 关键字对他的参数(一个异步任务)执行一个异步等待。

3、await 首先检查操作是否已经完成,如果完成了,就继续运行(同步方法)。否则,他会暂停 async 方法,并返回,将控制权交给调用方,留下一个 未完成的 Task。一段时间后,操作完成,async方法再恢复运行。

异步方法签名的返回值:

1、Task:如果调用方法想通过调用异步方法获取一个T类型的返回值,那么签名必须为Task;

2、Task:如果调用方法不想通过异步方法获取一个值,仅仅想追踪异步方法的执行状态,那么我们可以设置异步方法签名的返回值为Task;

3、void:如果调用方法仅仅只是调用一下异步方法,不和异步方法做其他交互,我们可以设置异步方法签名的返回值为void,这种形式也叫做“调用并忘记”。

注意事项

1、异步方法并不等于多线程,异步方法并不能在新线程中执行,除非手动放入;

2、异步方法耗时可能很高,避免可能的线程过高,占用过多资源,有的时候可以简写,如下:

static async Task<string> Main(string[] args)
{
    string s = await readtext(1);
    Console.Read();
}

static Task<string> readtext(int num)
{
    if(num==1)
    {
    return File.ReadAllTextAsync(@"D:\vs2019\netcode\AsyncandAwait\1.txt");
    }
    else
    {
       throw new ArgumentException();
    }
}

注意:返回值为Task<string>类型的,仅简单的转发结果,可以不使用Async和Await,可以如上方式书写。

3、如果在异步方法暂停一段时间,不要用Tread.Sleep(),因为它会阻塞调用线程,而要用await.Task.Delay();

4、需要提前终止任务,比如请求超时、用户取消请求。很多异步方法都有CancellationToken参数,用于获得提前终止执行的信号。






 您阅读本篇文章共花了: 

免责声明
本站内容均为博客主本人日常使用记录的存档,如侵犯你的权益请联系:lifei@zaiheze.com 546262132@qq.com 沟通删除事宜。本站仅带访问端口形式使用,已杜绝搜索引擎爬取。

扫描二维码推送至手机访问。

版权声明:本文由LIFEI - blog发布,如需转载请注明出处。

本文链接:http://www.lifeiai.com/?id=293

分享给朋友:

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。