首页 > 学院 > 开发设计 > 正文

【C#】线程之Task

2019-11-17 02:52:32
字体:
来源:转载
供稿:网友

【C#】线程之Task

Task开启线程

  有两种启动方式:

    1.构造创建线程,然后启动

      

            var taskForAction = new Task(() =>            {                //do something            });        taskForAction.Start();

      注:构造所有的重载并没有传入Func函数的,而且我们这个时候看线程池中活动线程数会发现改变

            //打印线程池中线程活动数            PRintAvailabeWorkThreadNum();            var taskForAction = new Task(() =>            {                //do something            });        taskForAction.Start();            PrintAvailabeWorkThreadNum();

  

  输出结果:

      

  

    2.直接使用静态方法   

            //打印线程池中线程活动数            PrintAvailableWorkThreadNum();            var taskForAction = Task.Run(() => Console.WriteLine("print string for Action"));            var taskForFunc = Task.Run(() => "return string for Func<string>");            PrintAvailableWorkThreadNum();            //Result内部会调用Wait,所以这里不需要调            Console.WriteLine(taskForFunc.Result);

   同样的,直接调用静态方法来创建一个线程,并返回当前正在执行的线程副本以供我们调用,Result只有传递进去的是Func函数才会在返回的Task中存在,如果传入的是Action函数,Result是不存在的, 这个时候线程活动数量也会改变。

    

取消任务

   已经在 【C#】线程协作式取消这章里面好好讨论过如何去取消了,如何注册回调函数等技术了.

任务完成时重新开启一个任务(ConintueWith)

我们有时候想在执行完一个任务以后,再开始做一个其他的任务,这个时候如果我们用Wait就会堵塞线程,如果我们用线程嵌套的方式去做,会浪费资源并损害的伸缩性。

  

           //这样会堵塞我们的线程            Task.Run(() =>            {                //do something            }).Wait();            Task.Run(() =>            {                //do another thing            });            //虽然不会堵塞线程了,但这样会浪费资源            Task.Run(() =>            {                Task.Run(() =>                {                    //do something                }).Wait();                Task.Run(() =>                {                    //do another thing                });            });

   CLR给我们提供了另一个方法:ContinueWith.

    这个方法会不会堵塞当前的线程,并且会等第一个任务做好了以后再做第二个任务(当然可以开启多个)

       var t = Task.Run(() =>            {                int index = 0;                int count = 0;                while (index != 5)                {                    count += index;                    Console.WriteLine("Task:" + index++);                    Thread.Sleep(1 * 1000);                }                return count;            });            t.ContinueWith(task =>            {                //这里的参数Task,就是我们上面那个线程对象(t),可以用于获取结果集,状态等数据                Console.WriteLine("First continue task:" + task.Status);                Console.WriteLine("First continue task:" + (task.Result + 100)+"/n");            });            t.ContinueWith(task =>            {                Console.WriteLine("Second continue task:" + task.Status);                Console.WriteLine("Second continue task:" + (task.Result - 100));            });            t.ContinueWith(task =>            {                //Do another thing            });

   ContinueWith方法延伸

    需求肯定是很复杂的,比如我们希望在各种状态(取消,完成,失败等)情况下执行各种ContinueWith的方法,这个时候我们需要关注一个枚举类型:TaskContinuationOptions, 以下给出官方的定义:

  

namespace System.Threading.Tasks{    // Summary:    //     Specifies the behavior for a task that is created by using the System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task>,System.Threading.CancellationToken,System.Threading.Tasks.TaskContinuationOptions,System.Threading.Tasks.TaskScheduler)    //     or System.Threading.Tasks.Task<TResult>.ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>>,System.Threading.Tasks.TaskContinuationOptions)    //     method.    [Serializable]    [Flags]    public enum TaskContinuationOptions    {        // Summary:        //     Default = "Continue on any, no task options, run asynchronously" Specifies        //     that the default behavior should be used. Continuations, by default, will        //     be scheduled when the antecedent task completes, regardless of the task's        //     final System.Threading.Tasks.TaskStatus.        None = 0,        //        // Summary:        //     A hint to a System.Threading.Tasks.TaskScheduler to schedule a task in as        //     fair a manner as possible, meaning that tasks scheduled sooner will be more        //     likely to be run sooner, and tasks scheduled later will be more likely to        //     be run later.        PreferFairness = 1,        //        // Summary:        //     Specifies that a task will be a long-running, course-grained Operation. It        //     provides a hint to the System.Threading.Tasks.TaskScheduler that oversubscription        //     may be warranted.        LongRunning = 2,        //        // Summary:        //     Specifies that a task is attached to a parent in the task hierarchy.        AttachedToParent = 4,        //        // Summary:        //     Specifies that an System.InvalidOperationException will be thrown if an attempt        //     is made to attach a child task to the created task.        DenyChildAttach = 8,        //        // Summary:        //     Prevents the ambient scheduler from being seen as the current scheduler in        //     the created task. This means that operations like StartNew or ContinueWith        //     that are performed in the created task will see System.Threading.Tasks.TaskScheduler.Default        //     as the current scheduler.        HideScheduler = 16,        //        // Summary:        //     In the case of continuation cancellation, prevents completion of the continuation        //     until the antecedent has completed.        LazyCancellation = 32,        //        // Summary:        //     Specifies that the continuation task should not be scheduled if its antecedent        //     ran to completion. This option is not valid for multi-task continuations.        NotOnRanToCompletion = 65536,        //        // Summary:        //     Specifies that the continuation task should not be scheduled if its antecedent        //     threw an unhandled exception. This option is not valid for multi-task continuations.        NotOnFaulted = 131072,        //        // Summary:        //     Specifies that the continuation task should be scheduled only if its antecedent        //     was canceled. This option is not valid for multi-task continuations.        OnlyOnCanceled = 196608,        //        // Summary:        //     Specifies that the continuation task should not be scheduled if its antecedent        //     was canceled. This option is not valid for multi-task continuations.        NotOnCanceled = 262144,        //        // Summary:        //     Specifies that the continuation task should be scheduled only if its antecedent        //     threw an unhandled exception. This option is not valid for multi-task continuations.        OnlyOnFaulted = 327680,        //        // Summary:        //     Specifies that the continuation task should be scheduled only if its antecedent        //     ran to completion. This option is not valid for multi-task continuations.        OnlyOnRanToCompletion = 393216,        //        // Summary:        //     Specifies that the continuation
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表