一、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博客