最新內容優先發佈於個人博客:小虎技術分享站,隨後逐步搬運到博客園。 創作不易,如果覺得有用請在Github上為博主點亮一顆小星星吧! 博主開始學習編程於11年前,年少時還只會使用cin 和cout ,給單片機點點燈。那時候,類似async/await 和future/promise 模型的認知還不是 ...
最新內容優先發佈於個人博客:小虎技術分享站,隨後逐步搬運到博客園。
創作不易,如果覺得有用請在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
來消費非同步產生的列表
本文展示了基本的非同步方法使用,計劃後續再撰文記錄非同步方法的取消功能等更高級話題。
演示效果如下:
參考鏈接
https://www.cnblogs.com/cplemom/p/14290789.html