【问题标题】:Parallel ForEach and Tasks not working SAFE并行 ForEach 和任务不工作安全
【发布时间】:2018-10-04 07:33:52
【问题描述】:

我正在尝试将文本拆分为具有多个拆分字符的单词。

使用普通的 ForEach,我得到了 590 个单词,但是当我使用 Parallel.ForEach 或 Task 时,我得到了随机的单词数:560、583、579、....

我也用过 Task.WaitAll(mytasklis) ,但也没有用。

这是我的代码:

foreach (string _Word_ in _Input_Text.Split(_split_chars)) 
 {

      if ((_Word_.Length != 0) && (_Word_.Length <= 50) && 
         (string.IsNullOrEmpty(_Word_) == false))
           {

              ALL_WORDS.Add(_Word_.ToLower());

           }
 }

这有什么问题?我只是用 Parallel.ForEach 更改正常的 foreach 或将此代码设置在新的 Task(()=> 中,但没有用。

谢谢

【问题讨论】:

  • 我将继续假设ALL_WORDS 不是线程安全集合。使用ConcurrentBag&lt;string&gt; 或其他东西。你能说明ALL_WORDS的定义吗?
  • 无论如何我都质疑在这种特定情况下使用多线程 - 它不太可能让它更快。

标签: c# foreach parallel-processing


【解决方案1】:

正如@John 所说,您应该使用线程安全集合,例如ConcurrentBag

或者您可以像这样使用 LINQ 的强大功能:

var ALL_WORDS = _Input_Text.Split(_split_chars)
    .AsParallel()
    .Where(x => x.Length != 0 && x.Length <= 50 && !string.IsNullOrEmpty(x))
    .ToList();

注意:正如@Matthew Watson 和@bommelding 所提到的,这种并行性并不意味着您会获得性能提升,您应该在有或没有并行性的情况下对其进行衡量。

@Shayan Firoozi 的注释:
谢谢各位!

结果,是的,你是对的,并行性并没有让这段代码更快,有时也会让它变慢!

但对我来说,LINQ 的速度令人惊奇。 一直教导 LINQ 比传统的 for/foreach 慢得多,但在这种情况下,我的代码运行速度 快了 50%!!

【讨论】:

  • 然后用.AsParallel()和不用.AsParallel()来衡量这个,因为我认为马修·沃森也是对的。
  • 是的,也许。不知道会不会有性能提升,这个应该由提问者来衡量,这只是做并行查询的一种方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 2013-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多