并行。用于失败(C#)
我写了一些代码:并行。用于失败(C#),c#,parallel-processing,C#,Parallel Processing,我写了一些代码: class Program { public const int count = 3000; static List<int> list = new List<int>(); static void DoWork(int i) { list.Add(i); } static void Ma
class Program
{
public const int count = 3000;
static List<int> list = new List<int>();
static void DoWork(int i)
{
list.Add(i);
}
static void Main(string[] args)
{
while (true)
{
Stopwatch s = new Stopwatch();
s.Start();
Parallel.For(0, count + 1, DoWork);
s.Stop();
Console.WriteLine("\n Elapsed: " + s.Elapsed.ToString());
Console.WriteLine("Expected: {0}", count + 1);
Console.WriteLine("count: {0}", list.Count);
Console.ReadKey();
list = new List<int>();
}
}
}
类程序
{
公共常数整数计数=3000;
静态列表=新列表();
静态空腔定位销(int i)
{
列表.添加(i);
}
静态void Main(字符串[]参数)
{
while(true)
{
秒表s=新秒表();
s、 Start();
平行。对于(0,计数+1,道工);
s、 停止();
Console.WriteLine(“\n已运行:+s.eassed.ToString());
WriteLine(“应为:{0}”,计数+1);
WriteLine(“count:{0}”,list.count);
Console.ReadKey();
列表=新列表();
}
}
}
但预期不会有结果(
并非所有周期都在Console.WriteLine调用之前完成
使用并行有什么问题。对于?而言,列表
类不是线程保存的。您不能在并行循环中修改它(没有问题)。使用集合形式命名空间列表
不是线程安全的类。您应该改用一个并发集合,或者实现自己的同步
有关
并行的详细信息,请参阅。对于,您正在运行一个名为的。由于.Net中的列表集合不是线程安全的,因此它的操作(如Add()
)不是原子的。基本上,在一个线程上调用Add()可以破坏另一个线程的Add()在完成之前。您需要为代码创建线程安全的并发集合
试试这个:
using System.Threading.Tasks;
class Program
{
public const int count = 3000;
static ConcurrentBag<int> bag = new ConcurrentBag<int>();
static void DoWork(int i)
{
bag.Add(i);
}
static void Main(string[] args)
{
while (true)
{
Stopwatch s = new Stopwatch();
s.Start();
Parallel.For(0, count + 1, DoWork);
s.Stop();
Console.WriteLine("\n Elapsed: " + s.Elapsed.ToString());
Console.WriteLine("Expected: {0}", count + 1);
Console.WriteLine("count: {0}", bag.Count);
Console.ReadKey();
bag = new ConcurrentBag<int>();
}
}
}
使用System.Threading.Tasks;
班级计划
{
公共常数整数计数=3000;
静态ConcurrentBag=新ConcurrentBag();
静态空腔定位销(int i)
{
添加(i);
}
静态void Main(字符串[]参数)
{
while(true)
{
秒表s=新秒表();
s、 Start();
平行。对于(0,计数+1,道工);
s、 停止();
Console.WriteLine(“\n已运行:+s.eassed.ToString());
WriteLine(“应为:{0}”,计数+1);
WriteLine(“count:{0}”,bag.count);
Console.ReadKey();
bag=新的ConcurrentBag();
}
}
}
ConcurrentBag是最接近线程安全列表的东西。请记住,因为我们处理的是未知的调度,所以整数不会按顺序排列