C# 之 Task、async和 await 、Thread 的简单整理

1、异步方法(async/await)

在 C# 5.0 中出现的 async 和 await ,让异步编程变得更简单。

此方法利用了 .NET Framework 4.5 及更高版本、.NET Core 和 Windows 运行时中的异步支持。

编译器可执行开发人员曾进行的高难度工作,且应用程序保留了一个类似于同步代码的逻辑结构。

async 用在方法定义前面,await只能写在带有async标记的方法中。

注意await异步等待的地方,await后面的代码和前面的代码执行的线程可能不一样

async关键字创建了一个状态机,类似yield return 语句;await会解除当前线程的阻塞,完成其他任务

这里实现同步异步读取文件内容的方式。

我们可以看到异步读取代码和同步读取代码基本一致。async/await让异步编码变得更简单,我们可以像写同步代码一样去写异步代码。

注意一个小问题:异步方法中方法签名返回值为Task,代码中的返回值为T。

代码中GetContentAsync的签名返回值为Task,而代码中返回值为string。牢记这一细节对我们分析异步代码很有帮助。

异步方法签名的返回值有以下三种:

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

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

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

参考代码如下

复制代码
        static void Main(string[] args)
        {
            //Console.WriteLine(" Environment.CurrentDirectory "+ Environment.CurrentDirectory);
            string content = GetContentAsync(Environment.CurrentDirectory + @"/test.txt").Result;
            //调用同步方法
            //string content = GetContent(Environment.CurrentDirectory + @"/test.txt");
            Console.WriteLine(content);
            Console.ReadKey();
        }
 
        /// <summary>
        /// 异步读取文件内容
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        async static Task<string> GetContentAsync(string filename)
        {
 
            FileStream fs = new FileStream(filename, FileMode.Open);
            var bytes = new byte[fs.Length];
            //ReadAync方法异步读取内容,不阻塞线程
            Console.WriteLine("开始读取文件");
            int len = await fs.ReadAsync(bytes, 0, bytes.Length);
            string result = Encoding.UTF8.GetString(bytes);
            return result;
        }
 
        /// <summary>
        /// 同步读取文件内容
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        static string GetContent(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open);
            var bytes = new byte[fs.Length];
            //Read方法同步读取内容,阻塞线程
            int len = fs.Read(bytes, 0, bytes.Length);
            string result = Encoding.UTF8.GetString(bytes);
            return result;
        }

2、Task、async和 await 、Thread 简单小结

最后我们简单记住一些特性,就可以有个较好的理解他们了:

1)async/await是基于Task的

2)而Task是对ThreadPool的封装改进,主要是为了更有效的控制线程池中的线程(ThreadPool中的线程,我们很难通过代码控制其执行顺序,任务延续和取消等等);

3)ThreadPool基于Thread的,主要目的是减少Thread创建数量和管理Thread的成本。

4)async/await Task是C#中更先进的,也是微软大力推广的特性

5)我们在开发中可以尝试使用Task来替代Thread/ThreadPool,处理本地IO和网络IO任务是尽量使用async/await来提高任务执行效率。

相关推荐
棉晗榜3 小时前
C# HttpClient配置具有tls指纹发起跟浏览器一样的请求解决反爬虫防护
开发语言·爬虫·c#
吴可可1233 小时前
在CAD中点击添加多段线顶点的方法与实现
c#
全栈小54 小时前
【C#】.net core,静态方法线程安全解析,面试时经常被问的线程安全就藏在里面
安全·c#·.netcore
天下无敌笨笨熊5 小时前
C#视频开发心得
开发语言·c#·音视频
LccKyI5 小时前
C#基础编程 面试题汇总(三)
笔记·c#
半亩码田7 小时前
C#转Python第4.1篇:当 try-catch 遇上 try-except:异常处理的大不同
开发语言·python·c#
z落落8 小时前
C# Modbus-RTU 串口读写设备+CRC16+邮件告警
开发语言·c#
DS随心转小程序8 小时前
Gemini只能导出了一部分Word文档,很少的一部分,不是我这个窗口所有的对话内容?
开发语言·人工智能·c#·word·豆包·deepseek·ai导出鸭
格林威8 小时前
C# 相机图像配合频闪光源:实现高速稳定拍摄的几个方法
开发语言·网络·人工智能·数码相机·计算机视觉·c#·视觉检测
CSDN_RTKLIB8 小时前
CAD绘图单位
c#