zoukankan      html  css  js  c++  java
  • [转载]Net 4.0 Parallel 编程 Task

    http://www.cnblogs.com/Henllyee/archive/2011/06/06/net_parallel_programing.html

    http://www.cnblogs.com/dajiang02/archive/2012/02/08/2342198.html

    在上篇文章中我们看过了如何创建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();
  • 相关阅读:
    如何用ASP.NET加密Cookie数据过程分析
    PHP监控linux服务器负载情况分析解决方案
    我发现了博客的一个小问题
    人生总是有太多的失望
    小公司根据实据情况部署实施Linux集群网站
    刚刚收到光棍短信祝福了!
    我对你的期望有点过了
    PHP在接下来的几年内将是主主流的
    不付出一定不会有收获!
    关于创建RootDesigner的文章
  • 原文地址:https://www.cnblogs.com/fx2008/p/2376895.html
Copyright © 2011-2022 走看看