多线程Task

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //new Program().SimpleTask();
            new Program().TaskOfConditions();
        }

        //最简单的task使用
        public void taskUse()
        {
            //执行一个无返回值的任务
            Task.Run(() =>
            {
                Console.WriteLine("runing...");
            });

            //执行一个返回int类型结果的任务
            Task.Run(() =>
            {
                return new Random().Next();
            });

            //声明一个任务,仅声明,不执行
            Task t = new Task(() =>
            {
                Console.WriteLine("");
            });
        }


        //使用TaskFactory 工厂异步任务
        public void Factory()
        {
            List> tasks = new List>();
            TaskFactory factory = new TaskFactory();
            tasks.Add(factory.StartNew(()=> 
            {
                return 1;
            }));
            tasks.Add(factory.StartNew(()=> 
            {
                return 2;
            }));
            foreach (var t in tasks)
            {
                Console.WriteLine("Task:{0}",t.Result);
            }
        }

        //Task中的异常
        //异步任务中发生异常会导致任务抛出 TaskCancelException 的异常,仅表示任务退出,程序应当捕获该异常;然后,立即调用 Task 进行状态判断,获取内部异常
        public void SimpleTask()
        {
            var task = Task.Run(() =>
              {
                  Console.WriteLine("SimpleTask");
                  Task.Delay(1000).Wait();
              });
            try
            {
                task.Wait();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            //task.IsCompletedSuccessfully 而不是 task.IsCompleted,这两者的区别在于,前者只有在任务正常执行完成,无异常,无中途退出指令的情况下才会表示已完成,而 task.IsCompleted 则仅仅表示“任务完成”
            if (task.IsCompletedSuccessfully)
            {
                Console.WriteLine("IsCompleted");
            }
        }
        //获取当前线程上下文对象
        public void TaskSynchronizationContext()
        {
            //在没有 Task 的时代,处理异步上下文到同步上下文是一件非常复杂的事情,
            //在 Task 出现以后,提供了 TaskScheduler 任务调度器,让我们可以非常方便的在异步线程中访问 UI 线程的资源
            var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();
            var t1 = Task.Factory.StartNew(() =>
              {
                  return 1;
              });
            t1.ContinueWith((atnt) => 
            {
                Console.WriteLine("从这里访问 UI 线程的资源");
            }, UISyncContext);
            //从上面的代码可以发现,仅仅需要调用 TaskScheduler.FromCurrentSynchronizationContext() 
            //获得当前线程的同步上下文,然后在执行异步任务的时候传入,即可访问当前线程创建的 UI 资源
        }

        /// 
        /// 设置当前程序可使用的线程池大小,但是,SetMaxThreads 的值不应该小于托管服务器的 CPU 核心数量,否则,变量 available 的值将显示为 false,表示未成功设置线程池上限
        /// 
        /// 注意:ThreadPool 上的所有线程都是后台线程,也就是说,其IsBackground属性是true,在托管程序退出后,ThreadPool 也将会退出。
        public void ThreadPoolUse()
        {
            var available = ThreadPool.SetMaxThreads(8, 16);
            Console.WriteLine("Result:{0}",available);
        }

        /// 
        /// 在创建 Task 的时候,我们可能需要做一些长时间运行的业务,这个时候如果使用默认的 ThreadPool 资源,在并发状态下,
        /// 这是不合适的,因为该任务总是长时间的占用线程池中的资源,导致线程池数量受限,这种情况下,
        /// 可以在创建任务的时候使用指定 TaskCreationOptions.LongRunning 方式创建 Task
        /// 
        /// 
        ///当TaskFactory 收到这样一个类型的任务时,将会为这个任务开辟一个独立的线程,而不是从 ThreadPool 中创建
        public void LongTask()
        {
            Task.Factory.StartNew(() =>
            {
                Console.WriteLine("LongRunning Task");
            },TaskCreationOptions.LongRunning);
        }
        /// 
        /// 有条件的Task
        /// Task 内部提供多种多样的基于队列的链式任务管理方法,通过使用这些快捷方式,
        /// 可以让异步队列有序的执行,比如ContinueWith(),ContinueWhenAll(),ContinueWhenAny(),WaitAll(),
        /// WaitAny(),WhenAll(),WhenAny()
        /// 
        public void TaskOfConditions()
        {
            var oreder1 = Task.Run(() =>
              {
                  Console.WriteLine("Order 1");
              });
            oreder1.ContinueWith((task) => 
            {
                Console.WriteLine("Order 1 Is Completed");
            });

            var t1 = Task.Run(() => { Task.Delay(1500).Wait(); Console.WriteLine("t1"); });
            var t2 = Task.Run(() => { Task.Delay(2000).Wait(); Console.WriteLine("t2"); });
            var t3 = Task.Run(() => { Task.Delay(3000).Wait(); Console.WriteLine("t3"); });
            Task.WaitAll(t1, t2, t3);
            //t1,t2,t3完成后输出下面的消息
            Console.WriteLine("t1,t2,t3 Is Complete");

            var t4 = Task.Run(() => { Task.Delay(1500).Wait(); Console.WriteLine("t4"); });
            var t5 = Task.Run(() => { Task.Delay(2000).Wait(); Console.WriteLine("t5"); });
            var t6 = Task.Run(() => { Task.Delay(3000).Wait(); Console.WriteLine("t6"); });
            Task.WaitAny(t4, t5, t6);
            // 当任意任务完成时,输出下面的消息,目前按延迟时间计算,在 t4 完成后立即输出下面的信息
            Console.WriteLine("t4,t5,t6 Is Complete");

            var t7 = Task.Run(() => { Task.Delay(1500).Wait(); Console.WriteLine("t7"); });
            var t8 = Task.Run(() => { Task.Delay(2000).Wait(); Console.WriteLine("t8"); });
            var t9 = Task.Run(() => { Task.Delay(3000).Wait(); Console.WriteLine("t9"); });
            var whenAll = Task.WhenAll(t7, t8, t9);
            // WhenAll 不会等待,所以这里必须显示指定等待
            whenAll.Wait();
            // 当所有任务完成时,输出下面的消息
            Console.WriteLine("t7,t8,t9 Is Complete");

            var t10 = Task.Run(() => { Task.Delay(1500).Wait(); Console.WriteLine("t10"); });
            var t11 = Task.Run(() => { Task.Delay(2000).Wait(); Console.WriteLine("t11"); });
            var t12 = Task.Run(() => { Task.Delay(3000).Wait(); Console.WriteLine("t12"); });
            var whenAny = Task.WhenAny(t10, t11, t12);
            // whenAny 不会等待,所以这里必须显示指定等待
            whenAny.Wait();
            // 当任意任务完成时,输出下面的消息,目前按延迟时间计算,在 t10 完成后立即输出下面的信息
            Console.WriteLine("t10,t11,t12 Is Complete");
            /*
             值得注意的是,当调用 WhenAll 方法时,会返回执行任务的状态,此状态是所有任务的统一状态,如果执行了 3 个任务,而其中一个出错,则返回任务状态表示为:Faulted,如果任意任务被取消,则状态为:Canceled;
             当调用 WhenAny() 方法时,表示任意任务完成即可表示完成,此时,会返回最先完成的任务信息
              注意:WhenAll 和 WhenAny 方法正常执行,无异常,无取消,则所返回的完成状态表示为:RanToCompletion
             */

        }
    }
}

 

你可能感兴趣的:(C#,ASP.NET)