一、TaskCompletionSource类的作用
TaskCompletionSource类回调代码转换为可以等待的Task,TaskCompletionSource本身不是可等待的,它也不是有效的异步方法返回类型。一旦TaskCompletionSource给了你一个任务,你可以简单地返回那个任务,就像你在异步方法中做其他任何事情一样。
二、代码示例
static void Main(string[] args){TaskCompletionSource<bool> tcs1= new TaskCompletionSource<bool>();Task.Run( () => ChoiceTicket(tcs1));Task.Run( () => PayForMoney(tcs1));Console.ReadKey();}static async void PayForMoney(TaskCompletionSource<bool> tcs){await tcs2.Task;Console.WriteLine("选购支付宝支付");tcs.SetResult(true);Thread.Sleep(3000);Console.WriteLine("支付完成");Console.WriteLine("跳到火车票软件完成");}static async Task<bool> ChoiceTicket(TaskCompletionSource<bool> tcs){Console.WriteLine("选购火车票");Console.WriteLine("跳转到到支付页面");tcs2.SetResult(10);await tcs.Task;Console.WriteLine("订票完成");return tcs.Task.Result;}
简单的讲TaskCompletionSource可以实现Task异步等待的功能,await TaskCompletionSource.task会在其他线程TaskCompletionSource.setResult执行后再继续执行。
代码:
1 private string AwaitByTaskCompleteSource(Func<Task<string>> func)2 {3 var taskCompletionSource = new TaskCompletionSource<string>();4 var task1 = taskCompletionSource.Task;5 Task.Run(async () =>6 {7 var result = await func.Invoke();8 taskCompletionSource.SetResult(result);9 });
10 var task1Result = task1.Result;
11 Debug.WriteLine($"3. AwaitByTaskCompleteSource end:{task1Result}");
12 return task1Result;
13 }
var task1Result = task1.Result;会暂停执行,直到taskCompletionSource.SetResult(result);赋值后才会继续执行。Task.result也会实现暂停功能,但是Task无法定义一个可以赋值的全局变量,taskCompletionSource可以不要实体Task的任务,实现暂停功能。
var tt = Task<int>.Run(() =>{for (int i = 0; i < 300; i++){Console.Write(1);}return 10;});var t1 = tt.Result;Task.Run(() =>{for (int i = 0; i < 300; i++){Console.Write(2);} });
var t1 = tt.Result该方法也是Task的一种暂停等待功能,在需要Task.result的地方会卡死等待task执行完后再继续向下执行。该运行结果是先输出1,再输出2,如果没有Task.result代码,则是1和2交替输出。
参考文献:
C# 异步转同步 TaskCompletionSource-CSDN博客
C# dotnet 使用 TaskCompletionSource 实现暂停功能-CSDN博客
C#中的TaskCompletionSource-CSDN博客