zoukankan      html  css  js  c++  java
  • .Net并行库介绍——Parallel

    Parallel.Invoke

    这个函数的功能和Task有些相似,就是并发执行一系列任务,然后等待所有完成。和Task比起来,省略了Task.WaitAll这一步,自然也缺少了Task的相关管理功能。它有两种形式:

    Parallel.Invoke( params Action[] actions);
    Parallel.Invoke(Action[] actions,TaskManager manager,TaskCreationOptions options);

    第二种方式可以自定义一个TaskManager对任务的执行线程进行管理(第一种方式用的是默认的TaskManager.Default)。

    示例如下:
    static void Main(string[] args)
    {
        var actions = new Action[]{
            () => ActionTest("test 1"),
            () => ActionTest("test 2"),
            () => ActionTest("test 3"),
            () => ActionTest("test 4")};

        Console.WriteLine("Parallel.Invoke 1 Test");
        Parallel.Invoke(actions);

        Console.WriteLine();

        Console.WriteLine("Parallel.Invoke 2 Test");
        Parallel.Invoke(actions, new TaskManager(new TaskManagerPolicy(1, 1, 2)), TaskCreationOptions.None);
    }

    static void ActionTest(object value)
    {
        Console.WriteLine(">>> thread:{0}, value:{1}",
        Thread.CurrentThread.ManagedThreadId, value);
    }

    输出结果如下:
    Parallel.Invoke 1 Test
    >>> thread:3, value:test 1
    >>> thread:3, value:test 2
    >>> thread:4, value:test 3
    >>> thread:5, value:test 4

    Parallel.Invoke 2 Test
    >>> thread:7, value:test 1
    >>> thread:7, value:test 2
    >>> thread:8, value:test 3
    >>> thread:7, value:test 4

    可见,由于第二次指定了最多只能使用两个线程来执行,故只有两个Task并发执行。

    Parallel.ForEach和Parallel.For

    Parallel.ForEachParallel.For用得要更加广泛一些,他可以根据一个数据源来生成一些任务(Parallel.Invoke需要事先生成这些任务),同时并发执行这些任务。基本示例如下:
    static void Main(string[] args)
    {
        var data = new object[] { "test 1", "test 2", "test 3" };

        Console.WriteLine("Parallel.ForEach Test");
        Parallel.ForEach(data, item => ActionTest(item));

        Console.WriteLine();

        Console.WriteLine("Parallel.For Test");
        Parallel.For(0, data.Length, index => ActionTest(data[index]));
    }

    这两个函数都有多种重载形式,提供了许多控制功能,由于用得不是很多,这里就不一一介绍了。但有一点不是很好:如果需要用TaskManager的话,不得不用那最复杂的那一种形式。希望最终版本的时候会提供更合理的重载形式,毕竟TaskManager还是很常用的(虽然目前的TaskManager功能薄弱了点),而那些复杂的参数不是很常用的。因此,这里提供了两个常用的扩展方法的封装:
    public static class ParallelExtend
    {
        public static void ParallelForEach<T>(this IEnumerable<T> source, Action<T> hanlder)
        {
            Parallel.ForEach(source, hanlder);
        }

        public static void ParallelForEach<T>(this IEnumerable<T> source, Action<T> hanlder, TaskManagerPolicy policy)
        {
            using (var manager = new TaskManager(policy))
            {
                Parallel.ForEach(source,
                    () => 0,
                    (item, index, state) => hanlder(item),
                    local => { },
                    manager,
                    TaskCreationOptions.None);
            }
        }
    }
    通过扩展方法的方式用起来还是比较方便的。

  • 相关阅读:
    Oracle SQL语句收集
    SqlParameter In 查询
    SQL 性能优化
    Entity Framework
    【XLL API 函数】 xlfSetName
    【XLL API 函数】xlfUnregister (Form 2)
    【XLL API 函数】xlfUnregister (Form 1)
    【Excel 4.0 函数】REGISTER 的两种形式以及VBA等效语句
    【Excel 4.0 函数】REGISTER
    【Bochs 官方手册翻译】 第一章 Bochs介绍
  • 原文地址:https://www.cnblogs.com/TianFang/p/1373426.html
Copyright © 2011-2022 走看看