gpt4 book ai didi

vb.net - Parallel.ForEach 每次都会给出不同的结果

转载 作者:行者123 更新时间:2023-12-04 05:03:26 26 4
gpt4 key购买 nike

请帮我将以下循环转换为并行循环。我尝试使用 Parallel.ForEach 和 ConcurrentBag 而不是 HashSet,但奇怪的是“Matched”每次都会返回不同的结果。

我想不通...是因为线程安全问题吗?

关键字列表包含大约 500 个唯一字符串,每个长度为 1-3 个单词。

项目包含大约 10000 个项目。

原始代码:

    Dim Items As IEnumerable(Of Item) = Db.Items.GetAll

Dim Keywords As HashSet(Of String)
Dim Matched As HashSet(Of Item)

For Each Item In Items

For Each Keyword In Keywords

If Regex.IsMatch(Headline, String.Format("\b{0}\b", Keyword), RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant) Then
If Not Matched.Contains(Item) Then
Matched.Add(Item)
End If

End If

Next

Next

尝试将其转换为
Dim Items As IEnumerable(Of Item) = Db.Items.GetAll

Dim Keywords As HashSet(Of String)
Dim Matched As Concurrent.ConcurrentBag(Of Item)

Threading.Tasks.Parallel.ForEach(Of Item)(Items, Sub(Item)
For Each Keyword In Keywords
If Regex.IsMatch(Item.Title, String.Format("\b{0}\b", Keyword), RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant) Then
If Not Matched.Contains(Item) Then
Matched.Add(Item)
End If
Continue For
End If
Next
End If

最佳答案

是的,您的代码当然不是线程安全的。使用线程安全集合不会使您的代码自动成为线程安全的,您仍然需要正确使用它们。

你的问题是在 Contains() 之后完成但在 Add() 之前在一个线程上调用,Add()可以在另一个线程上调用(在 Contains() 执行时也可能发生同样的情况)。

您需要做的是:

  • 使用锁定(这意味着您不再需要使用线程安全集合);或
  • 使用类似 ConcurrentHashSet . .Net 中没有这样的类,但是可以使用 ConcurrentDictionary相反(即使它不完全符合您的需求)。而不是您调用Contains()然后 Add() , 你可以做 Matched.TryAdd(Item, True) , 其中 True是不是因为ConcurrentDictionary需要一些值(value)。
  • 关于vb.net - Parallel.ForEach 每次都会给出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15834003/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com