NET4.0多线程编程---Tasks

写在前面的话

  不得不说4.0里面新增的task实在是让人耳目一新,曾经在thread里面查找当线程abort等等操作的时候有没有相应的事件,就像gridview在分页、绑定的时候会产生事件一样,但是在thread里面是没有找到。然而task里面这些都实现了,虽然不是以事件的方式实现,但是它真的实现了。很让人兴奋。

一、概述 

  在上一篇文章.NET4.0多线程编程---Cooperative Cancellation提到线程池没有提供任何内在的方法告诉我们操作什么时候完成,在线程完成了以后,我们也没有任何方法可以获取一个返回值。

  为了弥补上述不足,微软在.NET4.0里面提出了任务的概念(Task),下面的两种方式产生的结果是一样的

ThreadPool.QueueUserWorkItem(Sum, 5);//使用线程池 new Task(Sum, 5).Start();//使用Task

  上面线程池是由cpu自己操作的,而task需要程序手动去Start。

  对于task,在使用其构造函数的时候可以传递Action(向上面只传递没有参数的函数),也可以传递Action<object>(有参数的函数),还可以传递CancelationToken(用于接收取消的命令,这样描述感觉才对,token啊)

二、等待一个Task完成,并且获取其执行结果

  要想获取执行结果,我们必须构造一个Task<TResult>对象,TResult必须要和即将要和绑定的方法的返回值相匹配。等待调用其Wait方法。写了一个小例子。

代码

namespace Alex.Net4MultiThread.MyTask { internal class OwnTask {
public static void Main() { Task<int> t = new Task<int>(n => Sum((int)n), 10); t.Start(); t.Wait();//等待 Console.WriteLine(t.Result);//900 } private static int Sum(int n) { int sum = 0; for (; n < 100; n++) { Thread.Sleep(10); sum += 10; } return sum; } }
}

  在上面代码中如果在调用Wait时,task已经开始执行,那么程序会阻止当前线程一直等待到task完成为止(犹如thread所示)。而如果在调用wait时,task还没有开始执行,那么当前线程是不会阻止的。

  当在一个任务中产生异常,任务会正常返回,但是当调用Wait或者Result的时候系统会抛出System.AggregateException异常。

三、取消一个Task

  可是使用CancellationTokenSource来取消一个task,如果考虑到又可能要取消一个task,那么对应的方法应该接受一个CancellationToken参数(用于通知被取消)。上代码。

代码

namespace Alex.Net4MultiThread.MyTask { internal class OwnTask {
public static void Main() { CancellationTokenSource cts = new CancellationTokenSource(); Task<int> t = new Task<int>(() => Sum(cts.Token, 10), cts.Token);
t.Start(); cts.Cancel();//取消 try { //在调用Wait或者Result时会返回目标操作中的异常 Console.WriteLine(t.Result);//900 } catch (AggregateException ex) { ex.Handle(e => e is OperationCanceledException); Console.WriteLine("Sum was canceled"); } } private static int Sum(CancellationToken ct, int n) { int sum = 0; for (; n < 100; n++) { ct.ThrowIfCancellationRequested();//如果被通知取消,则会抛出异常 sum += 10; } return sum; } } }

  上面的操作真的是很让人激动的,比起Thread.Abort实在是太好了。对于取消。如果在取消时Task还没有Start,那么task将不会执行。

四、当其他任务完成的时候,自动开始一个新的任务

  在前面的例子中,我们wait一个task或者要获取一个task的Result,等待其实是很花费系统资源的,在Task编程模式下,大多时候我们都无需等待,只需注册一个新的task,该task在当前task完成时执行,此时我们可以对Result进行操作。

代码

namespace Alex.Net4MultiThread.MyTask { internal class OwnTask {
public static void Main() { Task<int> t = new Task<int>(n=>Sum((int)n),10);
t.Start();// Task cwt = t.ContinueWith(task => Console.WriteLine("The sum is :"

          +task.Result));//900 Console.Read(); } private static int Sum(int n) { int sum = 0; for (; n < 100; n++) { sum += 10; } return sum; } } }

  上面代码中新的任务(注册)是通过ContinueWith来完成的,该函数也返回一个task,但是一般情况下直接忽略其返回值,而应该将注意力集中在其逻辑,“注册什么,注册的task做什么,应该在什么时候让其执行。。。”,比如在上例中,注册的task在主task结束时打印出主task的执行结果。

  其实上面的代码是在主task完成之后执行某注册的task,其实ContinueWith函数还接受一个TaskContinuationOptions枚举参数。有8-9个值吧,我主要演示3个,具体功能如其名所示。

代码

t.ContinueWith(task => Console.WriteLine("The sum is :"+task.Result), TaskContinuationOptions.OnlyOnRanToCompletion);//主task成功时执行当前产生的task t.ContinueWith(task => Console.WriteLine("The sum is :" + task.Result), TaskContinuationOptions.OnlyOnFaulted);//主task失败执行当前产生的task t.ContinueWith(task => Console.WriteLine("The sum is :" + task.Result), TaskContinuationOptions.OnlyOnCanceled);//主task取消执行当前产生的task

时间: 2025-01-04 23:54:28

NET4.0多线程编程---Tasks的相关文章

.NET4.0多线程编程---Cooperative Cancellation

在多线程编程中线程池是不得不提的,在.net4.0之前一般对于线程池的说法是,把需要的线程交给线程池,我们自己将更多的关注点放在业务上,个人认为这既是线程池的优点也是缺点---加入线程池之后人为无法控制,也没有内在的方法告知线程的执行结果. 今天早晨拜读了Jeffrey的著作26th章.根据自己的理解今天主要学习“如何取消线程池中的线程”. 首先介绍System.Thread命名空间下面的两个类: CancellationToken ,其实这是一个结构,它主要传播有关应取消操作的通知. Canc

VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载

VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程     转载 #include <stdio.h>#include <stdlib.h>#include <pthread.h> void* tprocess1(void* args){       int i=1;       while(i<=10){            printf("process1:%d\n",i);

5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结

5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task 5天玩转C#并行和多线程编程 —— 第四天 Task进阶  一.多线程带来的问题 1.死锁问题  前面我们学习了Task的使用方法,其中Task的等待机制让我们瞬间爱上了它,但是如果我们在调用Task.WaitAll方法等待所有线程时,如果有一个Task一直不返

C#多线程编程

C#多线程编程 一.使用线程的理由 1.可以使用线程将代码同其他代码隔离,提高应用程序的可靠性. 2.可以使用线程来简化编码. 3.可以使用线程来实现并发执行. 二.基本知识 1.进程与线程:进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源. 2.前台线程和后台线程:通过Thread类新建线程默认为前台线程.当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛出异常. 3.挂起(Suspend)和唤醒(Resume):由于线程的执行

你必须掌握的多线程编程

1.多线程编程必备知识 1.1 进程与线程的概念 当我们打开一个应用程序后,操作系统就会为该应用程序分配一个进程ID,例如打开QQ,你将在任务管理器的进程选项卡看到QQ.exe进程,如下图: 进程可以理解为一块包含了某些资源的内存区域,操作系统通过进程这一方式把它的工作划分为不同的单元.一个应用程序可以对应于多个进程. 线程是进程中的独立执行单元,对于操作系统而言,它通过调度线程来使应用程序工作,一个进程中至少包含一个线程,我们把该线程成为主线程.线程与进程之间的关系可以理解为:线程是进程的执行

iOS/MacOS多线程编程GCD

GCD和Block一起,使得iOS多线程编程变得简单优雅许多.如此优雅简单的多线程API真希望C和C++标准中也会有 One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD). This technology takes the thread management code you would normally write in your own applications a

.NET面试题解析(07)-多线程编程与线程同步

系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等,本文只是从常见面试题的角度(也是开发过程中常用)去深入浅出线程相关的知识.如果想要系统的学习多线程,没有捷径的,也不要偷懒,还是去看专业书籍的比较好. 常见面试题目: 1. 描述线程与进程的区别? 2. 为什么GUI不支持跨线程访问控件?一般如何解决这个问题? 3. 简述后台线程和前台线程的区别? 4. 说说常

5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq

在上一篇博客5天玩转C#并行和多线程编程 —— 第一天 认识Parallel中,我们学习了Parallel的用法.并行编程,本质上是多线程的编程,那么当多个线程同时处理一个任务的时候,必然会出现资源访问问题,及所谓的线程安全.就像现实中,我们开发项目,就是一个并行的例子,把不同的模块分给不同的人,同时进行,才能在短的时间内做出大的项目.如果大家都只管自己写自己的代码,写完后发现合并不到一起,那么这种并行就没有了意义. 并行算法的出现,随之而产生的也就有了并行集合,及线程安全集合:微软向的也算周到

Android多线程编程之线程池学习篇(一)

Android多线程编程之线程池学习篇(一) 一.前言 Android应用开发中多线程编程应用比较广泛,而应用比较多的是ThreadPoolExecutor,AsyncTask,IntentService,HandlerThread,AsyncTaskLoader等,为了更详细的分析每一种实现方式,将单独成篇分析.后续篇章中可能涉及到线程池的知识,特此本篇分析为何使用线程池,如何使用线程池以及线程池的使用原理. 二.Thread Pool基础 进程代表一个运行中的程序,一个运行中的Android