Task 运用

Posted yingger

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Task 运用相关的知识,希望对你有一定的参考价值。

创建Task任务的方法

            // 法一 
            var tf = new TaskFactory();
            var t_a = tf.StartNew(() => Console.Write("create a task"));

            // 法二
            Task.Factory.StartNew(() => Console.Write("create a task")); 

            // 法三
            Task.Run(() => Console.Write("create a task"));

            // 法四
            var t = new Task(() => Console.Write("create a task"));
            t.Start();

            // 集合用法
            List<Task> list = new List<Task>();
            list.Add(Task.Run(() => strResult = GetString("aaa")));
            list.Add(Task.Run(() => myInt = GetInt(0)));
            list.Add(Task.Run(() => GetVoid()));

带返回值的Task

Task<int> task = new Task<int>(a => { return (int)a + 1; }, 1);
task.Start();
Console.WriteLine(task.Result);    //task.Result 获取返回值

Taske的WaitAll()方法,主线程等待WaitAll()参数内的所有线程执行完,会卡住页面,与WaitAll相近的方法还有 Wait(Int32) 和 Wait(TimeSpan) 方法阻止调用线程,WaitAny() 表示等待某个或多个Task执行完成

            DateTime startTime = DateTime.Now;     // Task开始时间
            List<Task> list = new List<Task>();
            list.Add(Task.Run(() => myInt = GetInt(10)));
            list.Add(Task.Run(() =>
            {
                Console.Write("事物开始!");  
                DateTime outTime = DateTime.Now.AddSeconds(20);   // 设置超时时间为20S
                bool bls = true;
                while (!(list[0].IsCompleted))    // 判断Task[0]是否完成
                { 
                    if (DateTime.Now > outTime)   // 判断是否超时 
                        bls = false;
                }
                DateTime sTime = startTime;       // Task运行开始时间
                DateTime endTime = DateTime.Now;  // Task运行结速时间
                if (bls)      
                    Console.Write("所有Task成功任务已完成,提交事物!");
                else
                    Console.Write("所有Task任务失败----超时----已结束,回滚事物!");

            }));
            // var a Task.Run(() => strResult = GetString("aaa"));
            // var b=Task.Run(() => strResult = GetString("bb"));
            // Task.WaitAll(a,b);  // 推荐用这种 
            Task.WaitAll(list.ToArray());

 

使用变量对Task方法结果赋值,保证页面不卡ContinueWith()方法,同时取前Task的变量值来处理

            string strResult = "";
            int myInt = 0;
            // 集合用法    不推荐,更推存var tss = new Task(()=> strResult=GetString("bbb")这种写法
            List<Task> list = new List<Task>();
            list.Add(Task.Run(() => strResult = GetString("aaa")));   // 给 strResult在Task中赋值
            list.Add(Task.Run(() => myInt = GetInt(0)));              // 给 myInt在Task中赋值
            list.Add(Task.Run(() => GetVoid()));
            list[2].ContinueWith(task =>         // ContinueWith()延续任务 指Task完成第一个任务再下延续任务
            {
                bool bls = true;
                Console.Write(strResult + myInt);  // 对变量strResult和myInt操作
                DateTime outTime = DateTime.Now.AddSeconds(5);        // 设置超时时间
                while (!list[0].IsCompleted || !list[1].IsCompleted)  //  判断这两个任务是否执行完?
                {
                    if (DateTime.Now > outTime)     // 判断是否超时
                        bls = false;
                }
                if (bls)
                    Console.Write("方案成功执行,提交事物!");
                else
                    Console.Write("方案执行失败,超时,回滚事物!");
            });

有反回值的Task,通过Result 属性获取Task的返回值

            Task<string> tasks = Task.Factory.StartNew<string>(() => {return GetString("ccc"); });
            string aaa = tasks.Result;
            
            Task<string> ts =new Task<string>(()=> {
                while (!tasks.IsCompleted)     // 判断tasks是否执行完成
                { }
                return GetString("ccc") +"     "+ tasks.Result;  // 通过tasks.Result获取tasks的返回值
            });
            ts.Start();
            string stsssssr = ts.Result;     // 通过ts.Result 获取ts的返回值
            Console.Write(stsssssr);

使用单独线程的任务

如果任务的代码需要运行很长时间,就应该使用TaskCreationOptions.LongRunning告诉任务调度器创建一个新线程,而不是使用线程池中的线程。此时线程可以不由线程池管理。当线程来自线程池时,任务调度器可以决定等待已经运行的任务完成,然后使用这个线程,而不是在线程池中创建一新的线程。对于长时间运行的线程,任务调度器会立即知道等待他们完成不是明智做法。

            Task<string> tasks = Task.Factory.StartNew<string>(() => {return GetString("ccc"); }, TaskCreationOptions.LongRunning);
            string aaa = tasks.Result;
            
            Task<string> ts =new Task<string>(()=> {
                while (!tasks.IsCompleted)
                { }
                return GetString("ccc") +"     "+ tasks.Result;  // 通过tasks.Result获取tasks的返回值
            }, TaskCreationOptions.LongRunning);
            ts.Start();
            string stsssssr = ts.Result;     // 通过ts.Result 获取ts的返回值
            Console.Write(stsssssr);

 

 

 

 

 

  

 

以上是关于Task 运用的主要内容,如果未能解决你的问题,请参考以下文章

Task 运用

如何运用领域驱动设计 - 值对象

Leetcode:Task Scheduler分析和实现

Spring定时器配置与运用,及Cron表达式的详解

Task运行过程分析1

使用Task.Wait而不是等待异步编程