c# – Parallels.ForEach与Foreach相同

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

我正在使用Parallels.ForEach如下

  1. private void fillEventDifferencesParallels(IProducerConsumerCollection<IEvent> events,Dictionary<string,IEvent> originalEvents)
  2. {
  3. Parallel.ForEach<IEvent>(events,evt =>
  4. {
  5. IEvent originalEventInfo = originalEvents[evt.EventID];
  6. evt.FillDifferences(originalEventInfo);
  7. });
  8. }

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

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

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

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

  1. public List<IDifferences> ShallowCompare(object orig,object changed,string currentName)
  2. {
  3. List<IDifferences> differences = new List<IDifferences>();
  4. foreach (MemberInfo m in orig.GetType().GetMembers())
  5. {
  6. List<IDifferences> temp = null;
  7.  
  8. //Go through all memberinfos until you find one that is a Property.
  9. if (m.MemberType == MemberTypes.Property)
  10. {
  11. PropertyInfo p = (PropertyInfo)m;
  12. string newCurrentName = "";
  13. if (currentName != null && currentName.Length > 0)
  14. {
  15. newCurrentName = currentName + ".";
  16. }
  17. newCurrentName += p.Name;
  18. object propertyOrig = null;
  19. object propertyChanged = null;
  20.  
  21. //Find the property Information from the orig object
  22. if (orig != null)
  23. {
  24. propertyOrig = p.GetValue(orig,null);
  25. }
  26.  
  27. //Find the property Information from the changed object
  28. if (changed != null)
  29. {
  30. propertyChanged = p.GetValue(changed,null);
  31. }
  32.  
  33. //Send the property to find the differences,if any. This is a SHALLOW compare.
  34. temp = objectComparator(p,propertyOrig,propertyChanged,true,newCurrentName);
  35. }
  36. if (temp != null && temp.Count > 0)
  37. {
  38. foreach (IDifferences difference in temp)
  39. {
  40. addDifferenceToList(differences,difference);
  41. }
  42. }
  43. }
  44. return differences;
  45. }

解决方法

我相信你可能会遇到线程上下文切换的成本.由于这些任务长时间运行,我可以想象在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,第一个任务已经完成,所以这个过程将继续.一个可能的解决方案如下.

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

猜你在找的C#相关文章