问题描述
我刚刚认识一些新的.NET并发集合像ConcurrentDictionary和ConcurrentQueue,我跑了一些测试,看看当我写平行队列会发生什么。
于是我就这样的:
私有静态无效ParallelWriteToQueue(队列< INT>队列)
{
秒表SW = Stopwatch.StartNew();
的Parallel.For(1,1000001中,(i)=> queue.Enqueue(ⅰ));
sw.Stop();
Console.WriteLine(常规INT队列 - + queue.Count +时间+ sw.ElapsedMilliseconds);
}
当我以为我得到了一个异常:
源阵列是不是足够长的时间。检查SRCINDEX和长度,以及阵列的下限。
所以这个队列无法处理的并发连接,队列为predicted。
但是,当我改变了队列字符串类型的,没有例外,并将结果写入类似
普通字符串队列 - 663209 time117
这意味着只有大约663k是EN-排队。
为什么会出现也不例外?
发生了什么事所有的不带连接排队的项目?
这是同样的功能与队列
私有静态无效ParallelWriteToQueue(队列<字符串>队列)
{
秒表SW = Stopwatch.StartNew();
的Parallel.For(1,100001,(ⅰ)=> queue.Enqueue(i.ToString()));
sw.Stop();
Console.WriteLine(常规字符串队列 - + queue.Count +时间+ + sw.ElapsedMilliseconds);
}
无论你是否得到一个异常无关,与你放入队列的类型。它具有不确定性,我可以复制的例外两种类型,我可以重现的情况下无一例外也为两种类型 - 不改变code
运行下面的代码片段显示了这一点:
INT异常= 0;
INT noExceptions = 0;
为(中间体X = 0 X - 小于100 ++ x)的
{
队列< INT> Q =新的队列和LT;诠释>();
尝试
{
的Parallel.For(1,1000001中,(i)=> q.Enqueue(ⅰ));
++ noExceptions;
}
抓住
{
++异常;
}
}
Console.WriteLine(运行出现异常:{0}运行没有:{1},异常noExceptions);
输出是一样的东西运行出现异常:96运行没有:4
原因是 - 正如其他人已经提到 - 即队列
不是线程安全的。这里发生的被称为比赛条件。
I'm just getting to know some of the new .NET concurrent collections like ConcurrentDictionary and ConcurrentQueue and I was running some tests to see what happens when I write parallel to the Queue.
So I ran this:
private static void ParallelWriteToQueue(Queue<int> queue)
{
Stopwatch sw = Stopwatch.StartNew();
Parallel.For(1,1000001,(i) => queue.Enqueue(i));
sw.Stop();
Console.WriteLine("Regular int Queue - " + queue.Count + " time" + sw.ElapsedMilliseconds);
}
And as I thought I got the next exception:
Source array was not long enough. Check srcIndex and length, and the array's lower bounds.
So this Queue can't handle concurrent en-queues as predicted.
But, When I changed the type of the queue to string, there was no exception, and the result writes something like
Regular string Queue - 663209 time117
Which means that only about 663k were en-queued.
Why was there no exception?
What happened to all of the not en-queued items?
this is the same function with Queue
private static void ParallelWriteToQueue(Queue<string> queue)
{
Stopwatch sw = Stopwatch.StartNew();
Parallel.For(1, 100001, (i) => queue.Enqueue(i.ToString()));
sw.Stop();
Console.WriteLine("Regular string Queue - " + queue.Count + " time" + +sw.ElapsedMilliseconds);
}
Whether or not you get an exception has nothing to do with the type you put in the queue. It is non-deterministic, I can reproduce the exception for both types and I can reproduce the case without exception also for both types - without changes to the code.
Running the following snippet shows this:
int exceptions = 0;
int noExceptions = 0;
for (int x = 0; x < 100; ++x)
{
Queue<int> q = new Queue<int>();
try
{
Parallel.For(1,1000001,(i) => q.Enqueue(i));
++noExceptions;
}
catch
{
++exceptions;
}
}
Console.WriteLine("Runs with exception: {0}. Runs without: {1}", exceptions, noExceptions);
The output is something like Runs with exception: 96. Runs without: 4
The reason is - as others already mentioned - that Queue
is not thread safe. What happens here is called "Race condition".
这篇关于队列&LT; T&GT;下并发给出不同的结果为不同类型的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!