- A+
所属分类:.NET技术
最新内容优先发布于个人博客:小虎技术分享站,随后逐步搬运到博客园。
创作不易,如果觉得有用请在Github上为博主点亮一颗小星星吧!
博主开始学习编程于11年前,年少时还只会使用cin
和cout
,给单片机点点灯。那时候,类似async/await
和future/promise
模型的认知还不是很够,因此一直使用着最传统的Thread
模型实现异步。顶多使用ThreadPool
线程池来实现对线程资源的复用。而现在我们有更现代方法,在.net
环境下可以使用现代C#
提供的async/await
关键字方便地实现基于任务异步模型的异步调用。
完整代码下载见:Github
一个基本的异步方法
假设我们定义以下这个异步方法模型,在函数上作用async
关键字实现在控制台异步输出字符串。
static async Task FooAsync() { Console.WriteLine("Foo."); }
突然发现VS2022的提示说由于没有Task.Run
或者await
还是同步方法。。。
根据这个提示我们修改上述的方法使之满足异步方法的要求
static async Task FooAsync() { Task.Run(() => Console.WriteLine("Foo.")); }
为了展示各种简单的异步方法,我们写了以下的demo来演示
namespace AsyncBasic { internal class Program { static async Task BasicFuncAsync() { await Task.Run( () => Console.WriteLine("Hello Basic Func Async.") ); } static async Task LoopFuncAsync() { for (int i = 0; i < 10; i++) { Console.WriteLine($"Loop func {i}."); await Task.Delay(100); } } static async Task FooAsync() { Console.WriteLine("Foo."); } static async Task<int> BasicFuncWithRetAsync() { Console.WriteLine("Basic func with return value."); await Task.Delay(1000); return 10086; } static async IAsyncEnumerable<int> GenerateEnumerableAsync() { for (int i = 0; i < 10; ++i) { yield return i; await Task.Delay(100); } } static async Task Main(string[] args) { Console.WriteLine("Hello Async Basic."); Task task1 = LoopFuncAsync(); Task task2 = BasicFuncAsync(); Task<int> task3 = BasicFuncWithRetAsync(); Task.WaitAny(task2, task3); Console.WriteLine($"Basic Func Async ret value: {task3.Result}"); Task.WaitAll(task1, task2, task3); Console.WriteLine($"Generate Enumerable Async"); await foreach (int i in GenerateEnumerableAsync()) { Console.WriteLine($"Async Enumerable: {i}"); } } } }
值得一提的是C# 8.0以后可以使用await foreach
来消费异步产生的列表
本文展示了基本的异步方法使用,计划后续再撰文记录异步方法的取消功能等更高级话题。
演示效果如下: