多线程——Task

简介: 背景:                 以前想用Semaphore来处理并发访问资源的问题,后来把方案拿给前辈们看的时候,他们说这样也行,但是最好用Task处理,比较简单。所以,顺便学习了下Task.




背景:

                以前想用Semaphore来处理并发访问资源的问题,后来把方案拿给前辈们看的时候,他们说这样也行,但是最好用Task处理,比较简单。所以,顺便学习了下Task.



使用task类创建并执行简单任务







等待任务的完成并获取返回值







使用ContinueWith方法在任务完成时启动一个新任务






创建父子任务和任务工厂的使用



<span style="font-size:12px;">namespace 创建父子任务和任务工厂的使用
{
    class Program
    {

        //通过task类创建的任务是顶级任务,可以通过使用TaskCreationOptions .AttachedToParent 标识把这些任务与创建他的任务相关联
        //所有子任务完成以后父任务才会结束操作
        //
        static void Main(string[] args)
        {

          #region 创建父子任务Demo
              //Task<string[]> parent = new Task<string[]>(state => {


              //      Console.WriteLine(state);
              //      string[] result = new string[2];
              //      //创建并启动子任务
              //      new Task(() => { result[0] = "任务1。。。"; },TaskCreationOptions .AttachedToParent ).Start ();
              //      new Task(() => { result [1]="任务2。。。";},TaskCreationOptions .AttachedToParent ).Start ();
              //      return result ;
              //  },"这里是父任务,并在处理过程中创建多个子任务,所有子任务完成以后才会执行。");

              //  //任务处理完成后执行的操作
              //  parent .ContinueWith (t=>{
              //      Array.ForEach(t.Result, r => Console.WriteLine(r));
              //  });

              //  //启动父任务
              //  parent .Start ();
              //  Console .ReadKey (); 
	    #endregion

          
          #region 任务工厂的使用


            Task parent=new Task(()=>{


                CancellationTokenSource cts =  new CancellationTokenSource();//为什么不包含一个参数的构造函数??????
            
                   //创建任务工厂
                     TaskFactory tf = new TaskFactory(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);


            //添加一组具有相同状态的子任务
            Task[] task=new Task[]{
            
                tf.StartNew (()=>{Console.WriteLine("我是任务工厂里的第一个任务");}),
                tf.StartNew (()=>{Console .WriteLine("我是任务工厂里的第二个任务");}),
                tf.StartNew (()=>{Console .WriteLine("我是任务工厂里的第三个任务");})
            
            };
           
            
            });

             parent .Start();
             Console.ReadKey();


            #endregion




        }
    }
}</span>


任务内部的实现和调度


      任务内部有一组构成任务状态的属性,表示任务的唯一ID,表示任务的执行状态(TaskStatus),任务创建时提供的回调函数的引用和传递给回调函数的数据对象AsyncState,对任务创建时的任务调度对象(TaskScheduler)的引用,对父任务的引用以及对执行上下文的引用和ManualResetEventSlim对象的引用。


       Task和Task<TResult>类都实现了标准的释放资源的接口,允许在任务完成处理的时候使用Dispose方法释放资源(关闭ManualResetEventSlim对象实例)。可以使用Task类的CurrentID属性获得正在执行的任务的ID,如果没有任务在执行CurrentID返回的值为null,currentID是一个int,可空类型的属性。任务执行的生命周期通过TaskStatus类似的一个值来表示,TaskStatus所包含的值为taskstatus


   

namespace 任务内部的实现和调度
{
    class Program
    {

       static  void TestDemo()
        {

            //获得同步上下文任务调度器
            TaskScheduler m_syncContextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();//表示一个处理将任务排队到线程中的低级工作对象

            //创建任务,并采用默认任务调度(线程池任务调度器)执行任务
            Task<int> task = new Task<int>(() =>
            {


                //执行复杂的计算任务
                Thread.Sleep(2000);//当前线程暂停2000
                int sum = 0;
                for (int i = 0; i < 100; i++)
                {
                    sum += i;

                }

                return sum;


            });



            var cts = new CancellationTokenSource();

            //任务完成时启动一个后续任务,并采用同步上下文任务调度器调度任务更新UI组件

            task.ContinueWith(t => { Console.WriteLine("采用SynchronizationContextTaskScheduler任务调度器更新UI。\r\n计算结果是:" + task.Result.ToString()); }, cts.Token, TaskContinuationOptions.AttachedToParent, m_syncContextTaskScheduler);

            task.Start();



        }
       

        static void Main(string[] args)
        {

            TestDemo();
        }
    }



    #region TaskStatus所包含的值:
        //    public enum TaskStatus
    //{


    //    Created = 0,
    //    WaitingForActivation = 1,
    //    WaitingToRun = 2,
    //    Running = 3,
    //    WaitingForChildrenToComplete = 4,
    //    RanToCompletion = 5,
    //    Canceled = 6,
    //    Faulted = 7

    //} 
    #endregion
}


    我们可以通过Task类的Exception属性获得任务在执行过程中的所有异常,Exception是一个AggregateException类型的属性。Task类提供了IsCanceled、IsCompleted、IsFaulted属性来获得任务的完成状态。通过ContinueWith、ContinueWhenAll、ContinueWhenAny和FromAsync创建的后续任务都处于WaitingForActivation状态,这个状态的任务会在父任务完成后自动执行。

 

       在任务内部由TaskScheduler类调度任务的执行,该类是一个抽象类,FCL中从他派生了两个派生类:ThreadPoolTaskScheduler线程池任务调度器和SynchronizationContextTaskScheduler同步上下文任务调度器。所有任务默认都是采用ThreadPoolTaskScheduler调度任务,他是采用线程池来执行任务,可以通过TaskScheduler类的静态属性Default获得对默认任务调度器的引用。SynchronizationContextTaskScheduler任务调度器能够用在Windowform、WPF等应用程序,他的任务调度是采用的GUI线程,所以他能同步更新UI组件,可以通过TaskScheduler类的静态方法FromCurrentSynchronizationContext获得对一个同步上下文任务调度起的引用。




目录
相关文章
|
1月前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法
|
1月前
|
Java C#
C#学习相关系列之多线程(六)----Task的初级使用
C#学习相关系列之多线程(六)----Task的初级使用
|
Dart 调度 Android开发
Flutter 95: 图解 Dart 单线程实现异步处理之 Task Queue
0 基础学习 Flutter,第九十五节:学习一下 MicroTask 和 EventTask 任务调度!
460 0
Flutter 95: 图解 Dart 单线程实现异步处理之 Task Queue
|
C#
WPF异常捕获三种处理 UI线程, 全局异常,Task异常
原文:WPF异常捕获三种处理 UI线程, 全局异常,Task异常 protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);RegisterEvents();} private void RegisterEvents(){//TaskScheduler.
2444 0
【多线程】Task
介绍   Task是.NET推出数据任务处理的工作类。位于System.Threading.Tasks命名空间下,通过命名空间也可以看出是个多线程类。 创建Task:   Task有很多构造函数,无参有参都有,想了解更多可以去官网查看。
773 0
|
C#
5天玩转C#并行和多线程编程 —— 第四天 Task进阶
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task 5天玩转C#并行和多线程编程 —— 第四天 Task进阶 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结    一、Task的嵌套    Task中还可以再嵌套Task,Thread中能不能这样做,我只能说我是没这样写过。
1525 0
|
C# Java 调度
5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task 5天玩转C#并行和多线程编程 —— 第四天 Task进阶 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结     对于多线程,我们经常使用的是Thread。
1293 0
|
并行计算 Java Windows
重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
原文:重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel) [源码下载] 重新想象 Windows 8 Store Apps (43) - 多线程之任务: Task 基础, 多任务并行执行, 并行运算(P...
773 0
|
vr&ar Windows 编译器
重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换
原文:重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换 [源码下载] 重新想象 Windows 8 Store Apps (44) - 多线程之异步编程: 经典和最新的异步编程模型, IA...
942 0