Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 并行。For循环退出过快_C#_Multithreading_Task_Parallel.for - Fatal编程技术网

C# 并行。For循环退出过快

C# 并行。For循环退出过快,c#,multithreading,task,parallel.for,C#,Multithreading,Task,Parallel.for,我试图将所有任务并行地添加到列表中,然后等待它们。代码: List<Task<bool>> tasks = new List<Task<bool>>(); Parallel.For(0, 500, file => { tasks.Add(SomeTask()); }); Console.WriteLine("Total tasks = " + tasks.Count); List tasks=newl

我试图将所有任务并行地添加到列表中,然后等待它们。代码:

List<Task<bool>> tasks = new List<Task<bool>>();                

Parallel.For(0, 500, file =>
{
  tasks.Add(SomeTask());
});

Console.WriteLine("Total tasks = " + tasks.Count);
List tasks=newlist();
Parallel.For(0500,文件=>
{
添加(SomeTask());
});
Console.WriteLine(“总任务数=“+tasks.Count”);
当我执行以下代码时,有时我会得到任务列表(tasks.Count)的大小为493、500或498。但这不是决定性的。我该怎么办呢?

你有一种叫做a的东西。您在没有同步的情况下从多个线程访问列表,这导致它处于一种奇怪的状态

您可以改用线程安全对象,如ConcurrentStack(或ConcurrentBag或ConcurrentQueue,具体取决于您对集合所做的操作):

ConcurrentStack tasks=new ConcurrentStack();
Parallel.For(0500,文件=>
{
tasks.Push(SomeTask());
});
Console.WriteLine(“总任务数=“+tasks.Count”);
任务返回方法(例如,
SomeTask
)通常返回速度非常快,并行调用通常会导致执行速度较慢

使用(非并行)LINQ构建任务集合要正常得多:

如果您的任务返回方法有一些CPU绑定的代码,并且您需要在线程池线程上运行
SomeTask
,那么您可以使用并行性。一种简单的方法是将调用包装到
任务中。运行

var tasks = Enumerable.Range(0, 500).Select(file => Task.Run(() => SomeTask())).ToList();
Console.WriteLine("Total tasks = " + tasks.Count);

您应该停止在这些任务中使用共享的非线程安全列表<代码>列表
不是线程安全的。或者在代码周围添加一个锁来操纵共享列表,或者使用一个适当的同步集合,或者做一些完全不同的不需要列表的事情(问题中的信息太少,最后一个选项太模糊,无法给出更多提示)。基本上,for循环不会很快退出,但是列表添加没有同步,因此一些更新丢失。最有可能的是,如果您查看其中的任务,您还会发现其他奇怪的事情,例如重复的条目或空引用。
List
List
)不是线程安全的;在
Parallel中执行
Add
。For
是危险的,很可能会导致不可预测的行为PLinq(Parallel Linq)而不是
Parallel。For
List tasks=Enumerable.Range(0,500).AsParallel().Select(file=>SomeTask()).ToList()除了关于列表和线程安全的注释外,使用parallel.For()向列表中添加500项绝对没有好处。为什么要使用并发堆栈?最接近列表的集合是并发包。
系统中可用的线程安全集合。集合。并发
命名空间包括:
并发字典
阻止集合
并发堆栈
并发队列
并发包
IProducerConsumerCollection
Stack觉得最适合我。几乎所有同时进行的收藏都能满足他的要求。
var tasks = Enumerable.Range(0, 500).Select(file => SomeTask()).ToList();
Console.WriteLine("Total tasks = " + tasks.Count);
var tasks = Enumerable.Range(0, 500).Select(file => Task.Run(() => SomeTask())).ToList();
Console.WriteLine("Total tasks = " + tasks.Count);