一个简单的Parallel.ForEach实现

一个简单的Parallel.ForEach实现在.net的TaskParallelLibrary中有一个很方便的功能Parallel.ForEach,可以实现多任务的并发执行,另外还带着栅栏功能,非常好用。但是这一功能必须需要clr4.0支持(CTP版的不大好用),对于低版本的.net要实现类似功能只有自己写一个了。codeproject上面文章PoorMan’sParallel.ForEachIterator中就有一种简单而…

大家好,又见面了,我是你们的朋友全栈君。

在.net的Task Parallel Library中有一个很方便的功能Parallel.ForEach,可以实现多任务的并发执行,另外还带着栅栏功能,非常好用。但是这一功能必须需要clr4.0支持(CTP版的不大好用),对于低版本的.net要实现类似功能只有自己写一个了。

codeproject上面文章Poor Man’s Parallel.ForEach Iterator中就有一种简单而有效的实现。但作者附录的代码有如下几个问题:

  1. 无法对每个并发任务分别制定不同的线程数
  2. 算法本身有点问题,任务执行完会报错
  3. 不能快速响应异常

针对以上几点,我对那段代码做了一点小改进,代码如下:

static class Parallel
{

    public static void ParallelForEach<T>(this IEnumerable<T> enumerable, Action<T> action, int NumberOfParallelTasks)
    {

        var syncRoot = new object();

        if (enumerable == null) return;

        var enumerator = enumerable.GetEnumerator();

        InvokeAsync<T> del = InvokeAction;

        var seedItemArray = new T[NumberOfParallelTasks];
        var resultList = new List<IAsyncResult>(NumberOfParallelTasks);
        var waitHanles = new List<WaitHandle>(NumberOfParallelTasks);

        for (int i = 0; i < NumberOfParallelTasks; i++)
        {

            lock (syncRoot)
            {

                if (!enumerator.MoveNext())
                    break;
                seedItemArray[i] = enumerator.Current;
            }

            var iAsyncResult = del.BeginInvoke(enumerator, action, seedItemArray[i], syncRoot, i, null, null);
            resultList.Add(iAsyncResult);
            waitHanles.Add(iAsyncResult.AsyncWaitHandle);
        }

        var taskCount = waitHanles.Count;

        for (int i = 0; i < taskCount; i++)
        {

            var index = WaitHandle.WaitAny(waitHanles.ToArray());
            del.EndInvoke(resultList[index]);
            resultList[index].AsyncWaitHandle.Close();
            waitHanles.RemoveAt(index);
            resultList.RemoveAt(index);
        }
    }

    delegate void InvokeAsync<T>(IEnumerator<T> enumerator,
    Action<T> achtion, T item, object syncRoot, int i);

    static void InvokeAction<T>(IEnumerator<T> enumerator, Action<T> action,
            T item, object syncRoot, int i)
    {

        //if (String.IsNullOrEmpty(Thread.CurrentThread.Name))
        // Thread.CurrentThread.Name =
        //String.Format(“Parallel.ForEach Worker Thread No:{0}”, i);

        bool moveNext = true;

        while (moveNext)
        {

            try
            {

                action.Invoke(item);
            }
            catch (Exception)
            {

                throw;
            }

            lock (syncRoot)
            {

                moveNext = enumerator.MoveNext();
                if (moveNext)
                    item = enumerator.Current;
            }
        }
    }
}

整个算法非常简洁,这里就不多介绍了。如果有错误欢迎指正。

转载于:https://www.cnblogs.com/TianFang/archive/2009/06/28/1512588.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161829.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 2013年8月最后一个周日

    2013年8月最后一个周日

    2021年8月25日
    60
  • Pytest(15)pytest分布式执行用例[通俗易懂]

    Pytest(15)pytest分布式执行用例[通俗易懂]前言平常我们功能测试用例非常多时,比如有1千条用例,假设每个用例执行需要1分钟,如果单个测试人员执行需要1000分钟才能跑完当项目非常紧急时,会需要协调多个测试资源来把任务分成两部分,于是执行时间

    2022年8月6日
    0
  • PyCharm导入本地模块

    PyCharm导入本地模块1.首先进入PyCharm的设置面板2.进入后点击Porjectinterpreter,点击右上角的add3.点击Existingenvironment这个选项,然后选择interpreter4.在弹出来的窗口中选择你的python安装目录关于查找目录位置,在windows中可以打开cmd然后输入wherepythonmacos中可以打开终端输入whichp…

    2022年8月25日
    6
  • 微信小程序实现下载功能(以下载视频为例)「建议收藏」

    微信小程序实现下载功能(以下载视频为例)「建议收藏」一、wx.downloadFile()方法:访问视频对应的Url,回调函数返回一个该视频文件的临时路径。wx.downloadFile({url:app.serverUrl+me.data.videoInfo.videoPath,success:function(res){//只要服务器有响应数据,就会把响应内容写入文件并进入success回调,业务需要自行判断是否下载到了想要的内容

    2022年6月22日
    311
  • 【经验总结—2】:深度学习数据集下载网站总结[通俗易懂]

    【经验总结—2】:深度学习数据集下载网站总结[通俗易懂]数据集是深度学习的基础,深度学习模型的好坏与数据集有着直接关联,这里给出一些搜索数据集的优秀网站,记得要一键三连哦!!1.CVDatasetsontheweb一个非常全的数据集总结网站,里面包含了目标检测、目标分类、目标识别、目标跟踪、语义分割、人体姿态数据集等。2.YetAnotherComputerVisionIndexToDatasets(YACVID)全,啥都有!3.阿里天池数据集不得不说,阿里nb!数据集种类丰富,分类明晰!不止如此,阿里每年都

    2022年10月7日
    0
  • asp中的session使用方法详解

    asp中的session使用方法详解ASP中: SESSION必须倚赖COOKIE才可用,SESSION是存储在服务器端的,而COOKIE是存储在客户端的,相对而言,SESSION的安全性和可靠程度都比COOKIE高 ASP.NET中 SESSION可以不依赖COOKIE而存在!!! 也就是说,从微软的方面来说,开始让SESSION摆脱COOKIE的束缚了!!Session数据是存储在服务器上的,C

    2022年7月15日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号