c#的async和await

调用和执行

C#5.0的引入了async和await两个修饰符,是异步编程的核心关键字,其中async 修饰后表示这个方法是可异步的,相当于贴上了一个异步标签;await顾名思义“等待”,表示被调方法内部在执行完await之前将会被阻塞。

这里涉及到的两个方法,简单的说就是,被调方法内部阻塞,主调方法异步(并行),用以下例子进行分析:

using System;
using System.Threading.Tasks;

namespace ConsoleApp2
{
	internal class Program
	{
		static void Main(string[] args)
		{
			DoSth();
			Console.WriteLine("wait1...");
			Console.ReadLine();
		}

		static async Task DoSth()
		{
			var task = await Loading();
			Console.WriteLine("wait2...");
			Console.WriteLine($"load end {task}");
		}

		static async Task<string> Loading()
		{
			Console.WriteLine("load 3 seconds");
			await Task.Delay(3000);
			return "ok";
		}
	}
}
  • dosth和loading,两个方法都被async修饰,表示是异步方法。
  • dosth中调用loading,而且是await方式,此时有两层含义,一是表示该方法(dosth)可以以异步方式“被”调用,二是dosth方法内部将会阻塞,直到loading执行完,方法内部才会继续往下执行“Console.WriteLine wait2…”。
  • dosth的调用方main是同步调用的,main内部不会阻塞,dosth和“Console.WriteLine wait1”将会并行执行。
  • 需要注意的是,loading方法中的代码并不全是异步的,你会发现在调用执行到await关键字之前的代码都是同步方式顺序执行的,所以会首先输出"load 3 seconds"。

以上例子在IDE中main方法中的DoSth()被绿色下划线提示“由于此调用不会等待,因此在调用完成之前,将继续执行当前方法”,此时可将DoSth返回值改为void,因为awiat不会等待void,此时方法限制为只能同步调用。

	static async void DoSth()
	{
		var task = await Loading();
		Console.WriteLine("wait2...");
		Console.WriteLine($"load end {task}");
	}

执行结果:

在这里插入图片描述

Task.run

Task.run是后台线程池执行,可以保护主线程不受耗时任务影响,例如下载文件,远程耗时请求等。
需注意异步方法的执行不一定是会以起线程的方式执行,这里有任务和状态机的概念,感兴趣的童鞋可以深入研究,而Task.run的存在使我们可以根据自己的业务复杂程度灵活指定线程执行。

Thread.sleep Or Task.delay

Task方法内部需要sleep时不能用thread.sleep 而是用task.delay,原因是例如在进行一些background线程执行一些初始化或者心跳时,会将这些方法的调用线程阻塞,导致异常情况出现,task.delay不阻塞线程,仅此而已。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值