• 第4章 使用任务并行库


    4.2 创建任务

    • 将学习一个新的异步编程范式 —— 任务并行库

    • 线程池可以认为是一个抽象层,向程序员隐藏了使用线程的细节。 线程池使用较为复杂,从线程池的工作线程中获得结果并不容易。我们需要自定义方式来获取,有了异常,还需要正确地传播到初始线程中。

    • .net framework4.0引入了一个关于异步操作的api——任务并行库(TPL)。TPL可认为是线程池之上的又一个抽象层。

    • TPL核心概念是任务。一个任务代表一个异步操作。该操作可以通过多种方式运行,可以使用或不使用独立线程运行。默认情况下,程序员无须知道任务是如何执行的。坏处是有些时候会导致诡异的错误。

    • 处理任务中的异常结果有多种方式。由于一个任务可能会由单个其他任务组成,这些任务可能依次拥有自己子任务。所以有一个AggregateException异常。可以将AggregateException异常看做是任务并行库编程中最上层的异常。这种异常可以捕获底层任务内所有异常,并允许单独处理这些异常。

    • 代码

    static void Main(string[] args)
    {
    	var t1 = new Task(()=>TaskMethod("task1"));
    	var t2 = new Task(()=>TaskMethod("task2"));
    	t2.Start();
    	t1.Start();
    	Task.Run(()=>TaskMethod("task3"));
    	Task.Factory.StartNew(()=>TaskMethod("task4"));
    	Task.Factory.StartNew(()=>TaskMethod("task5"),TaskCreationOptions.LongRunning);
    	Thread.Sleep(TimeSpan.FromSeconds(1));
    	Console.Read();
    }
    static void TaskMethod(string name)
    {
    	Console.WriteLine("task {0} is running on a thread id{1}. is thread pool thread:{2}",name,Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread);
    }
    
    • 工作原理
    • Task构造函数里传入lambda表达式作为action委托,启动两个任务。用Start方法启动任务后才会执行。
    • Task.Run、Task.Factory.StartNew运行另外两个任务(前者是后者的快捷方式)。这两个创建的任务会立刻工作,不用调Start方法。另外,后者标记为长时间运行,结果该任务将不会使用线程池,而是在单独线程中运行。

    4.3 使用任务执行基本的操作

    • 本节将描述如何从任务中获取结果值。
    Main方法
     #region 4.3
    Class4_3.TaskMethod("“t0”");
    Task<int> task = Class4_3.CreateTask("t1");
    task.Start();
    int result = task.Result;//获得任务结果值
    Console.WriteLine("result is {0}",result);
    
    task = Class4_3.CreateTask("t2");
    task.RunSynchronously();// 对当前的 TaskScheduler 同步运行Task。
    result = task.Result;
    Console.WriteLine("result is {0}", result);
    
    task = Class4_3.CreateTask("t3");
    task.Start();
    while (!task.IsCompleted)
    {
    	Console.WriteLine(task.Status);//任务状态
    	Thread.Sleep(500);
    }
    Console.WriteLine(task.Status);
    result = task.Result;
    Console.WriteLine("result is {0}", result);
     
    #endregion  
    			
    public  class Class4_3
    {
    	public static Task<int> CreateTask(string name)
    	{
    		return new Task<int>(()=>TaskMethod(name));
    	}
    
    	public static int TaskMethod(string name)
    	{
    		Console.WriteLine("task {0} is running on a thread id {1} .is thread pool thread:{2}",name,Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread);
    		Thread.Sleep(1000);
    		return 42;
    	}
    }
    

    工作原理

    • t1是任务方式运行。而t2通过那个方法被放到主线程中运行。可以避免使用线程池来执行非常短暂的操作。t0也是在主线程中同步运行,t0和t2很显然不是线程池中线程。
  • 相关阅读:
    oracle常用的sql语句
    Tomcat内存调优
    基于Linux服务器的Oracle自动备份以及定时清除
    Windows 中Oracle数据库定时备份与清除
    CentOS 7 root密码修改
    weblogic忘记用户密码
    weblogic修改密码
    通过python自动获取小说并下载
    Linux修改本机名称
    CentOS无法正常启动
  • 原文地址:https://www.cnblogs.com/anjun-xy/p/12002431.html
Copyright © 2020-2023  润新知