c# – Parallels.ForEach与Foreach相同

前端之家收集整理的这篇文章主要介绍了c# – Parallels.ForEach与Foreach相同前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
所有,

我正在使用Parallels.ForEach如下

private void fillEventDifferencesParallels(IProducerConsumerCollection<IEvent> events,Dictionary<string,IEvent> originalEvents)
    {
        Parallel.ForEach<IEvent>(events,evt =>
        {
            IEvent originalEventInfo = originalEvents[evt.EventID];
            evt.FillDifferences(originalEventInfo);
        });
    }

好的,所以我遇到的问题是我有一个这样的28个列表(一个测试样本,这应该能够扩展到200),而FillDifferences方法是相当耗时(每次呼叫约4秒).所以在一个正常的ForEach中运行的平均时间大约是100-130秒.当我并行运行相同的事情时,它需要相同的时间和Spikes我的cpu(Intel I5,2 Core,每个Core的2个线程),导致该应用程序在此查询运行时缓慢(这是在一个线程上运行这是由GUI线程产生的).

所以我的问题是,我做错了什么导致这需要相同的时间?我看到List不是线程安全的,所以我重写了使用IProducerConsumerCollection.是否有其他可能导致这种情况的陷阱?

FillDifferences方法调用使用反射的静态类,以找出原始对象和修改对象之间有多少差异.静态对象没有“全局”变量,只是调用方法的本地变量.

你们中有些人想看看什么是FillDifferences()方法.这是最终结束的地方:

public  List<IDifferences> ShallowCompare(object orig,object changed,string currentName)
    {
        List<IDifferences> differences = new List<IDifferences>();
        foreach (MemberInfo m in orig.GetType().GetMembers())
        {
            List<IDifferences> temp = null;

            //Go through all memberinfos until you find one that is a Property.
            if (m.MemberType == MemberTypes.Property)
            {
                PropertyInfo p = (PropertyInfo)m;
                string newCurrentName = "";
                if (currentName != null && currentName.Length > 0)
                {
                    newCurrentName = currentName + ".";
                }
                newCurrentName += p.Name;
                object propertyOrig = null;
                object propertyChanged = null;

                //Find the property Information from the orig object
                if (orig != null)
                {
                    propertyOrig = p.GetValue(orig,null);
                }

                //Find the property Information from the changed object
                if (changed != null)
                {
                    propertyChanged = p.GetValue(changed,null);
                }

                //Send the property to find the differences,if any. This is a SHALLOW compare.
                temp = objectComparator(p,propertyOrig,propertyChanged,true,newCurrentName);
            }
            if (temp != null && temp.Count > 0)
            {
                foreach (IDifferences difference in temp)
                {
                    addDifferenceToList(differences,difference);
                }
            }
        }
        return differences;
    }

解决方法

我相信你可能会遇到线程上下文切换的成本.由于这些任务长时间运行,我可以想象在ThreadPool上创建许多线程来处理它们.

> 0ms == 1线程
> 500ms == 2线程
> 1000 ms == 3线程
> 1500 ms == 4线程
> 2000 ms == 5线程
> 2500 ms == 6线程
> 3000 ms == 7线程
> 3500 ms == 8线程
> 4000 ms == 9线程

只有4000ms,第一个任务已经完成,所以这个过程将继续.一个可能的解决方案如下.

System.Threading.ThreadPool.SetMaxThreads(4,4);

猜你在找的C#相关文章