zoukankan      html  css  js  c++  java
  • Net 4.0 Parallel 编程(五)Task(中)

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

    Task Continuations

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [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属性来获取返回值。上面的代买我们也可以这么写:

    1
    2
    3
    4
    5
    6
    7
    8
    [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选项,那么就是分离嵌套的。我们看下面这段代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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选项:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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异常出来。来看一段示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    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
    作者:Henllyee Cui
    出处: http://henllyee.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
  • 相关阅读:
    WMI系统管理工具介绍和获取机器码
    QListWidget高性能加载图片数据
    2.5偏差方差分解
    QT图片旋转动画
    Qt实现数字滚动动画效果
    Qt动画使用总结
    线性回归--经验最小化,结构最小化,最大似然估计,最大后验估计
    获取国家2019年最新的省、市、区/县、街道、小区/居委会信息 包括港澳台
    .net 利用Emit将object转为DbParameter,DataTable转为List<>
    c#简单操作MongoDB_2.4
  • 原文地址:https://www.cnblogs.com/dajiang02/p/2344841.html
Copyright © 2011-2022 走看看