惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
D
DataBreaches.Net
S
Secure Thoughts
B
Blog
S
Schneier on Security
Y
Y Combinator Blog
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Full Disclosure
Engineering at Meta
Engineering at Meta
L
LangChain Blog
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Hacker News
The Hacker News
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
博客园 - 司徒正美
Help Net Security
Help Net Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy International News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
H
Heimdal Security Blog
Jina AI
Jina AI
C
Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
aimingoo的专栏
aimingoo的专栏
D
Docker
I
Intezer
C
Check Point Blog
Cloudbric
Cloudbric
小众软件
小众软件
V2EX - 技术
V2EX - 技术

博客园 - Henry Cui

招聘高级.Net工程师 Node.js Web开发(二)认识Express(上) Node.js Web开发(一)从零开始 Html5 Step by Step(二) 本地存储 HTML 5 Step by Step(一) 拖放API Git学习笔记(一)初识Git DDD中的Specification模式 Silverlight 4之旅(三)数据绑定(中) Silverlight 4之旅(二)数据绑定(上) Silverlight 4之旅(一) .Net 4.0 Parallel 编程之旅 .Net 4.0 Parallel 编程(九)Task中的数据共享(下) .Net 4.0 Parallel编程(八)Task中的数据共享(中) .Net 4.0 Parallel 编程(七)Task中的数据共享(上) .Net 4.0 Parallel 编程(六)Task(下) .Net 4.0 Parallel 编程(四) Task(上) Entity Framework Code-First(下) Entity Framework Code-First(上) Entity Framework POCO T4模板使用
.Net 4.0 Parallel 编程(五)Task(中)
Henry Cui · 2010-10-28 · via 博客园 - Henry Cui

2010-10-28 22:04  Henry Cui  阅读(2645)  评论()    收藏  举报

在上篇文章中我们看过了如何创建Task,本篇文章就各种类型Task的使用进行说明。

Task Continuations

首先我们来看看延续的Task,所谓的延续的Task就是在第一个Task完成后自动启动下一个Task。我们通过ContinueWith方法来创建延续的Task。我们假设有一个接受xml解析的服务,首先从某个地方接受文件,然后解析入库,最后返回回执是否解析正确:

        [TestMethod]
        public void TaskParallelPrint()
        {
            var ReceiveTask = new Task(() => ReceiveXml());
            var ResolveTask = ReceiveTask.ContinueWith<bool>((r) => ResolveXml());
            var SendFeedBackTask = ResolveTask.ContinueWith<string>((s) => SendFeedBack(s.Result));
            ReceiveTask.Start();
            Console.WriteLine(SendFeedBackTask.Result);
        }

在每次调用ContinueWith方法时,每次会把上次Task的引用传入进来,以便检测上次Task的状态,比如我们可以使用上次Task的Result属性来获取返回值。上面的代买我们也可以这么写:

        [TestMethod]
        public void TaskParallelPrint()
        {
            var SendFeedBackTask = Task.Factory.StartNew(() => ReceiveXml())
                                    .ContinueWith<bool>(s => ResolveXml())
                                    .ContinueWith<string>(r => SendFeedBack(r.Result));
            Console.WriteLine(SendFeedBackTask.Result);
        }

Detached Nested Tasks

有些情况下我们需要创建嵌套的Task,嵌套里面又分为分离的和不分离的。其创建的方式很简单,就是在Task的body里面创建一个新的Task。如果新的Task未指定AttachedToParent选项,那么就是分离嵌套的。我们看下面这段代码:

            var outTask = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Outer task beginning...");
                var childTask = Task.Factory.StartNew(() =>
                {
                    Thread.SpinWait(3000000);
                    Console.WriteLine("Detached nested task completed.");
                });
            });
            outTask.Wait();
            Console.WriteLine("Outer task completed.");
            Console.ReadKey();

我们可以看到运行结果是:

image

上面的代码中outTask.Wait()表示等待outTask执行完成。

Child Tasks

我们将上面的代码加上TaskCreationOptions选项:

            var outTask = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Outer task beginning...");
                var childTask = Task.Factory.StartNew(() =>
                {
                    Thread.SpinWait(3000000);
                    Console.WriteLine("Detached nested task completed.");
                },TaskCreationOptions.AttachedToParent);
            });
            outTask.Wait();
            Console.WriteLine("Outer task completed.");
            Console.ReadKey();

看到运行结果:

image

Cancellation Task

如何取消一个Task呢,我们通过cancellation的tokens来取消一个Task。在很多Task的Body里面包含循环,我们可以在轮询的时候判断IsCancellationRequested属性是否为True,如果是True的话,就可以停止循环以及释放资源,同时抛出OperationCanceledException异常出来。来看一段示例代码:

            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            var task = Task.Factory.StartNew(() =>
            {
                for (var i = 0; i < 10000000; i++)
                {
                    if (token.IsCancellationRequested)
                    {
                        Console.WriteLine("Task cacel started...");
                        throw new OperationCanceledException(token);
                    }
                    
                }
            },token);
            token.Register(() =>
            {
                Console.WriteLine("Canceled");
            });
            Console.WriteLine("Press enter again to cancel task");
            Console.ReadKey();
            tokenSource.Cancel();
            try
            {
                task.Wait();
            }
            catch (AggregateException e)
            {
                foreach (var v in e.InnerExceptions)
                    Console.WriteLine("msg: " + v.Message);

            }
            Console.ReadKey();

总结

本篇文章中我们看过了创建各种不同的Task以及如何取消Task,下篇文章中会就异常处理以及Task  Laizy进行说明

alt