日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET 6 新特性 WaitAsync

發布時間:2023/12/4 asp.net 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET 6 新特性 WaitAsync 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

.NET 6 新特性 WaitAsync

Intro

在 .NET 6 里新增加了一個 WaitAsync 的方法,用來異步地等待一個任務完成,異步等待的時候可以指定一個 Timeout 時間或者一個取消令牌 CancellationToken,在之前的版本中只有一個同步的 Wait 會等待任務的完成,不支持比較好的任務超時或取消處理,如果要實現的話要自己寫擴展,很多開源項目甚至微軟的項目里會有一個 TimeoutAfter 之類的擴展方法,有了 WaitAsync 之后就可以取代這些擴展了

Definition

新加的 WaitAsync 是一個擴展方法,定義如下:

public?static?Task?WaitAsync(this?Task?task,?TimeSpan?timeout); public?static?Task?WaitAsync(this?Task?task,?CancellationToken?cancellationToken); public?static?Task?WaitAsync(this?Task?task,?TimeSpan?timeout,?CancellationToken?cancellationToken); //?泛型版本 public?static?Task<TResult>?WaitAsync<TResult>(this?Task<TResult>?task,?TimeSpan?timeout); public?static?Task<TResult>?WaitAsync<TResult>(this?Task<TResult>?task,?CancellationToken?cancellationToken); public?static?Task<TResult>?WaitAsync<TResult>(this?Task<TResult>?task,?TimeSpan?timeout,?CancellationToken?cancellationToken);

Timeout Sample

來看一個 WaitAsync Timeout 的 使用示例:

var?tasks?=?new?List<Task>(); tasks.AddRange(new[]? {?Task.Delay(TimeSpan.FromSeconds(5)),Task.Delay(TimeSpan.FromSeconds(8)),Task.Delay(TimeSpan.FromSeconds(6)) }); Task?task?=?Task.WhenAll(tasks); try {await?task.WaitAsync(TimeSpan.FromSeconds(3)); } catch?(TimeoutException) {Console.WriteLine(nameof(TimeoutException)); } finally {Console.WriteLine(string.Join(",",?tasks.Select(t?=>?t.Status.ToString())));Console.WriteLine(task.Status); }await?Task.Delay(TimeSpan.FromSeconds(5)); Console.WriteLine(string.Join(",",?tasks.Select(t?=>?t.Status.ToString()))); Console.WriteLine(task.Status);

上面是一個使用 Timeout 的一個示例,當 Timeout 時間到了之后 Task 還沒完成就會 throw 一個 TimeoutException,但是并不會影響原來的任務繼續執行,除非自己能夠在 exception 的時候將原來的 Task 給中止,上面示例的輸出結果如下:

TimeoutException WaitingForActivation,WaitingForActivation,WaitingForActivation WaitingForActivation RanToCompletion,RanToCompletion,RanToCompletion RanToCompletion

可以看到,即使發生了 Timeout 也不會影響原來 Task 的執行

Cancellation Sample

接著來看一下 CancellationToken 的使用示例

var?cts?=?new?CancellationTokenSource(); var?tasks?=?new?List<Task>(); tasks.AddRange(new[] {Task.Delay(TimeSpan.FromSeconds(4)),Task.Delay(TimeSpan.FromSeconds(8)),Task.Delay(TimeSpan.FromSeconds(6)) }); var?task?=?Task.WhenAll(tasks); try {cts.CancelAfter(TimeSpan.FromSeconds(5));await?task.WaitAsync(cts.Token); } catch?(TaskCanceledException) {Console.WriteLine("Task?cancelled"); } finally {Console.WriteLine(string.Join(",",?tasks.Select(t?=>?t.Status.ToString())));Console.WriteLine(task.Status); }await?Task.Delay(TimeSpan.FromSeconds(5)); Console.WriteLine(string.Join(",",?tasks.Select(t?=>?t.Status.ToString()))); Console.WriteLine(task.Status);

輸出結果如下:

Task?cancelled RanToCompletion,WaitingForActivation,WaitingForActivation WaitingForActivation RanToCompletion,RanToCompletion,RanToCompletion RanToCompletion

使用 CancellationToken 的時候拋出的異常是 ?TaskCanceledException,而不是前面的 TimeoutException

而拋異常的行為和前面一樣,并不會影響原來 Task 的狀態

Another Sample

我們再來看一個既使用 Timeout 又使用取消令牌的一個示例吧

try {await?Task.Delay(TimeSpan.FromSeconds(5)).WaitAsync(TimeSpan.FromSeconds(3),?CancellationToken.None); } catch(Exception?ex) {Console.WriteLine(ex.GetType().Name); }try {using?var?cancellationTokenSource?=?new?CancellationTokenSource();cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(2));await?Task.Delay(TimeSpan.FromSeconds(5)).WaitAsync(TimeSpan.FromSeconds(10),?cancellationTokenSource.Token); } catch(Exception?ex) {Console.WriteLine(ex.GetType().Name); }

輸出結果如下:

TimeoutException TaskCanceledException

可以看出來哪一個條件 WaitAsync 的條件先滿足,拋出的就是哪一個對應的異常,兩個異常都沒有的就可以正常結束

More

WaitAsync 方法可以解決很多需要等待或者設置 Timeout 的場景,官方支持了這個 API 以后很多 TimeoutAfter/WithCancellationToken 之類的擴展方法可以去掉了

WaitAsync 拋出的異常需要針對處理,如果是 Timeout 則是 TimeoutException 如果是 CancellationToken Cancel 引發的異常則是 TaskCanceledException

References

  • https://github.com/dotnet/runtime/pull/48842

  • https://github.com/dotnet/runtime/blob/v6.0.0-preview.7.21377.19/src/libraries/Common/tests/System/Threading/Tasks/TaskTimeoutExtensions.cs

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/net6sample/WaitAsyncSample/Program.cs

總結

以上是生活随笔為你收集整理的.NET 6 新特性 WaitAsync的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。