Parallel.Foreach 内的竞争条件与列表
Race Condition inside Parallel.Foreach with List
我需要有关如何解决此竞争条件的帮助。下面是代码:
Task.Factory.StartNew(Sub()
' Do something...
dim newPeople as new List(Of Person)
dim myNames as ConcurrentBag(Of String) = GetNames()
Parallel.ForEach(myNames, Sub(name)
Dim person as new Person
person.Name = name
person.Gender = "MALE"
newPeople.Add(person)
GridView.BeginInvoke(Sub()
GridView.DataSource = newPeople
End Sub)
' Do something...
dim index as Integer = newPeople.FindIndex(Function(p) p.Name = name) ' Race condition error
newPeople(index).Gender = "FEMALE"
GridView.Invoke(Sub()
GridView.DataSource = newPeople
End Sub)
End Sub)
End Sub, param ,TaskCreationOptions.None)
这段代码主要做的是:
- 设置对象中人物的姓名和性别
- 在人员列表中添加此人员对象
- 在网格视图中显示(显示之前和之后)
- 做某事后,改变人的性别
- person 元素更新后在 gridview 中显示。
最终结果:gridview会在任务执行过程中自动改变状态。
我 运行 不知道如何解决这个问题。你能提出什么建议来解决这个问题吗?
我想我找到了答案。通过将 List(Of T)
更改为 ConcurrentBag(Of T)
解决了这个问题。根据this link
The ConcurrentBag<T>
collection, in the System.Collections.Concurrent
namespace, provides a multiset that is thread-safe. The collection
allows you to add and remove items freely from multiple threads
without having to worry about thread synchronisation. The fact that
the bag has no ordering allows it to be particularly efficient when
you have multiple threads or parallel tasks where each both adds and
removes items.
我需要有关如何解决此竞争条件的帮助。下面是代码:
Task.Factory.StartNew(Sub()
' Do something...
dim newPeople as new List(Of Person)
dim myNames as ConcurrentBag(Of String) = GetNames()
Parallel.ForEach(myNames, Sub(name)
Dim person as new Person
person.Name = name
person.Gender = "MALE"
newPeople.Add(person)
GridView.BeginInvoke(Sub()
GridView.DataSource = newPeople
End Sub)
' Do something...
dim index as Integer = newPeople.FindIndex(Function(p) p.Name = name) ' Race condition error
newPeople(index).Gender = "FEMALE"
GridView.Invoke(Sub()
GridView.DataSource = newPeople
End Sub)
End Sub)
End Sub, param ,TaskCreationOptions.None)
这段代码主要做的是:
- 设置对象中人物的姓名和性别
- 在人员列表中添加此人员对象
- 在网格视图中显示(显示之前和之后)
- 做某事后,改变人的性别
- person 元素更新后在 gridview 中显示。
最终结果:gridview会在任务执行过程中自动改变状态。
我 运行 不知道如何解决这个问题。你能提出什么建议来解决这个问题吗?
我想我找到了答案。通过将 List(Of T)
更改为 ConcurrentBag(Of T)
解决了这个问题。根据this link
The
ConcurrentBag<T>
collection, in the System.Collections.Concurrent namespace, provides a multiset that is thread-safe. The collection allows you to add and remove items freely from multiple threads without having to worry about thread synchronisation. The fact that the bag has no ordering allows it to be particularly efficient when you have multiple threads or parallel tasks where each both adds and removes items.