我想确认我的用于显示ConcurrentBag集合如何允许从不同线程修改同一集合对象而没有任何同步问题的工作代码是否可以接受?
我已经编写了有效的代码。只是希望让它遵循最佳实践。早先使用试图实现类似目标的List集合的相同代码显示为失败,并显示错误
"System.InvalidOperationException
HResult=0x80131509
Message=Collection was modified; enumeration operation may not execute.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
at System.Collections.Generic.List`1.Enumerator.MoveNext()
at Concurrent_Classes.ListWithMultithreads.Main(String[] args) ....
我正在比较多线程方案中的List和ConcurrentBag,以显示在我正在编写Collections的课程中,在这种方案中使用后者的实用性。
此代码有效:
class ConcurrentBagWithMultithreads
{
ConcurrentBag<string> currencies = new ConcurrentBag<string>();
void CurrencyBag1()
{
currencies.Add("INR");
currencies.Add("NZD");
currencies.Add("AUD");
currencies.Add("USD");
}
void CurrencyBag2()
{
currencies.Add("Euro");
currencies.Add("OMR");
currencies.Add("GBP");
currencies.Add("Dinar");
}
void CurrencyBag3()
{
currencies.Add("CAD");
currencies.Add("Yen");
currencies.Add("Franc");
currencies.Add("Lira");
}
static void Main()
{
ConcurrentBagWithMultithreads concurrentBagWithMultithreads = new ConcurrentBagWithMultithreads();
Thread worker1 = new Thread(concurrentBagWithMultithreads.CurrencyBag1);
Thread worker2 = new Thread(concurrentBagWithMultithreads.CurrencyBag2);
Thread worker3 = new Thread(concurrentBagWithMultithreads.CurrencyBag3);
worker1.Start();
worker2.Start();
worker3.Start();
Console.WriteLine("Testing....");
foreach (string currency in concurrentBagWithMultithreads.currencies)
{
Console.WriteLine($"The currency is = {currency}");
}
Console.Read();
}
}
此代码失败: ListWithMultithreads类 { 列表货币=新的List();
void CurrencyList1()
{
currencies.Add("INR");
currencies.Add("NZD");
currencies.Add("AUD");
currencies.Add("USD");
}
void CurrencyList2()
{
currencies.Add("NZD");
currencies.Add("OMR");
currencies.Add("GBP");
currencies.Add("USD");
}
void CurrencyList3()
{
currencies.Add("CAD");
currencies.Add("NZD");
currencies.Add("AUD");
currencies.Add("INR");
}
static void Main(string[] args)
{
ListWithMultithreads listWithMultithreads = new ListWithMultithreads();
Thread worker1 = new Thread(listWithMultithreads.CurrencyList1);
Thread worker2 = new Thread(listWithMultithreads.CurrencyList2);
Thread worker3 = new Thread(listWithMultithreads.CurrencyList3);
worker1.Start();
worker2.Start();
worker3.Start();
foreach (string currency in listWithMultithreads.currencies)
{
Console.WriteLine($"The currency is = {currency}");
}
Console.Read();
}
}
尽管大多数时候我使用ConcurrentBag集合获得一致的输出,但有时迭代循环不会显示出一组特定的CurrencyBag项目被漏掉了。换句话说,大约有90%的时间,我看到控制台带出了所有12个项目(这应该一直发生),但在其余的时间里,只有8个项目在显示。