zoukankan      html  css  js  c++  java
  • 《C#高级编程》读书笔记(十五):任务、线程和同步之二 任务

    1,任务

        为了更好地控制并行动作,可以使用System.Threading.Tasks名称空间中的Task类。任务表示应完成的某个工作单元。这个工作单元可以在单独的线程中运行,也可以以同步方式启动一个任务,这需要等待主调线程。

        启动任务的几种方法:可以使用TaskFactory类或Task类的构造函数和Start()方法。

        第一种方式:实例化TaskFactory类,在其中把TaskMetho方法传递给StartNew方法,就会立即启动任务。

        第二种方式:使用Task类的静态熟悉Factory来访问TaskFactory,以及调用StartNew()方法。

        第三种方式:使用Task类的构造函数。实例化Task对象时,任务不会立即执行,调用Task类的Start()方法启动任务。

        第四种方式:调用Task类的Run方法,立即启动任务。

            private static void Main(string[] args)
            {
                var tf = new TaskFactory();
                Task t1 = tf.StartNew(TaskMethod, "using a task factory");
    
                Task t2 = Task.Factory.StartNew(TaskMethod, "factory via a task");
    
                var t3 = new Task(TaskMethod,"using a task constructor and Start");
                t3.Start();
    
                Task t4 = Task.Run(() => TaskMethod("using the Run method"));
    
                Console.ReadKey();
            }
    
            static object taskMethoLock = new object();
    
            static void TaskMethod(object title)
            {
                lock (taskMethoLock)
                {
                    Console.WriteLine(title);
                }
            }

          执行结果:

    using a task factory
    factory via a task
    using the Run method
    using a task constructor and Start

        以上任务都是使用线程池中的线程,而且都是后台线程。

    2,同步任务

        任务也可以同步运行,以相同的线程作为主调线程,也就是在前台线程中运行。

            private static void RunSynchronousTask()
            {
                var t1 = new Task(TaskMethod,"run sync");
                t1.RunSynchronously();
            }

    3,使用单独线程的任务

        如果任务的代码应该长时间运行,应该使用TaskCreationOptions.LongRunning告诉任务调度器创建一个新的线程,而不是使用线程池中的线程。

    private static void LongRunningTask()
            {
                var t1 = new Task(TaskMethod,"long running",TaskCreationOptions.LongRunning);
                t1.Start();
            }

    4,连续任务

        连续任务通过在任务上调用ContinueWith()方法来定义。也可以使用TaskFactory类来定义。

            private static void Main(string[] args)
            {
                Task t1 = new Task(DoOnFirst);
                Task t2 = t1.ContinueWith(DoOnSecond);
                t1.Start();
                Console.ReadKey();
            }
    
            static void DoOnFirst()
            {
                Console.WriteLine($"doing some task {Task.CurrentId}");
            }
    
            static void DoOnSecond(Task t)
            {
                Console.WriteLine($"task {t.Id} finished");
                Console.WriteLine($"this task id {Task.CurrentId}");
                Console.WriteLine("do the cleanup");
                Thread.Sleep(3000);
            }

     5,任务层次结构

         任务也可以构成一个层次结构。一个任务启动一个新任务时,就启动了一个父/子层次结构。创建子任务的代码与创建父任务的代码相同,唯一的区别是这个任务从另一个任务内部创建。

            static void ParentAndChild()
            {
                var parent = new Task(ParentTask);
                parent.Start();
                Thread.Sleep(2000);
                Console.WriteLine(parent.Status);
                Thread.Sleep(4000);
                Console.WriteLine(parent.Status);
            }
    
            static void ParentTask()
            {
                Console.WriteLine($"task id {Task.CurrentId}");
                var child = new Task(ChildTask);
                child.Start();
                Thread.Sleep(1000);
                Console.WriteLine("parent started child");
            }
    
            static void ChildTask()
            {
                Console.WriteLine("child");
                Thread.Sleep(5000);
                Console.WriteLine("child finished");
            }
  • 相关阅读:
    98.公共汽车
    100.选菜(动态规划)01背包
    102.愤怒的LJF
    96.老鼠的旅行(动态规划)
    95.(01背包)之小吃
    94.Txx考试
    93.数字三角形W(深搜)
    POJ 3352 Road Construction (边双连通分量)
    POJ 3114 Countries in War(强联通分量+Tarjan)
    POJ 3592 Instantaneous Transference(强联通分量 Tarjan)
  • 原文地址:https://www.cnblogs.com/khjian/p/5790658.html
Copyright © 2011-2022 走看看