天天看點

C# 同步轉異步 TaskCompletionSource

當我們遇到一些異步執行又無法等待時的邏輯,比如動畫的執行。

而業務上又需要等待邏輯的完成,再去處理後續的操作。這時需要轉成異步方法

如下,同步執行一個動畫後,再輸出日志:

1     private async void TaskCompleteSourceAwait_OnClick(object sender, RoutedEventArgs e)
2     {
3         bool isCompleted = await AwaitByTaskCompletionAsync(new Storyboard() { Duration = new Duration(TimeSpan.FromSeconds(2)) });
4         Debug.WriteLine($"TaskCompleteSourceAwait_OnClick end:{isCompleted}");
5      

通過TaskCompletionSource如何轉化為異步方法,并等待動畫完成?

1     /// <summary>
 2     /// 執行動畫
 3     /// </summary>
 4     /// <param name="storyboard"></param>
 5     /// <returns></returns>
 6     public static async Task<bool> AwaitByTaskCompletionAsync(Storyboard storyboard)
 7     {
 8         var taskCompletionSource = new TaskCompletionSource<bool>();
 9 
10         Debug.WriteLine("Storyboard start");
11 
12         storyboard.Completed += OnStoryboardCompleted;
13         storyboard.Begin();
14 
15         void OnStoryboardCompleted(object sender, EventArgs e)
16         {
17             Debug.WriteLine("Storyboard end");
18             storyboard.Completed -= OnStoryboardCompleted;
19             taskCompletionSource.SetResult(true);
20         }
21         return await taskCompletionSource.Task;
22      

測試效果:

C# 同步轉異步 TaskCompletionSource

參考資料:

  • ​​深入了解 WPF Dispatcher 的工作原理(PushFrame 部分)​​
  • ​​使用任務簡化異步程式設計​​
  • ​​Async/Await異步程式設計中的最佳做法​​

同步轉異步

  • ​​C# 同步轉異步 TaskCompletionSource ​​
  • ​​C# 同步轉異步 AutoResetEvent​​

異步轉同步

  • ​​C# 異步轉同步 PushFrame​​
  • ​​C# 異步轉同步 TaskCompletionSource​​

死鎖

  • ​​C# 死鎖 Task/AutoResetEvent​​
  • ​​C# 死鎖 TaskCompletionSource​​

作者:​​唐宋元明清2188​​