C#学习相关系列之多线程---TaskCompletionSource用法(八)

简介: C#学习相关系列之多线程---TaskCompletionSource用法(八)

一、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交替输出。


相关文章
|
19天前
|
安全 C#
C# List基本用法
C# List基本用法
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
存储 缓存 安全
【C/C++ 关键字 存储类说明符 】 线程局部变量的魔法:C++ 中 thread_local的用法
【C/C++ 关键字 存储类说明符 】 线程局部变量的魔法:C++ 中 thread_local的用法
33 0
|
1月前
|
算法 安全 Unix
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
30 0
|
1月前
|
C#
C#学习系列相关之多线程(二)----Thread类介绍
C#学习系列相关之多线程(二)----Thread类介绍
|
1月前
|
C#
C#学习相关系列之数据类型类----嵌套类和嵌套方法(三)
C#学习相关系列之数据类型类----嵌套类和嵌套方法(三)
|
17天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
29天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
31 3
|
1月前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
58 0
|
1月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法