C# Parallel.Foreach-空任务

C# Parallel.Foreach-空任务,c#,task-parallel-library,task,parallel.foreach,C#,Task Parallel Library,Task,Parallel.foreach,我正在努力学习如何使用第三方物流。关于这个主题,我已经读了很多书,但我不明白为什么下面的代码示例会中断,而后面的代码示例会正常工作 我已经运行了一个单元测试来计算写入的记录,并且读取输出的文件以进行双重检查 失败: var tasks = new List<Task>(); Parallel.ForEach(File.ReadLines(featuresLocation), s => { var feature = Cr

我正在努力学习如何使用第三方物流。关于这个主题,我已经读了很多书,但我不明白为什么下面的代码示例会中断,而后面的代码示例会正常工作

我已经运行了一个单元测试来计算写入的记录,并且读取输出的文件以进行双重检查

失败:

var tasks = new List<Task>();

Parallel.ForEach(File.ReadLines(featuresLocation), s =>
            {
                var feature = CreateFeature(s);
                if (feature.HasValue)
                {
                    tasks.Add(Task.Factory.StartNew(() =>
                        {
                            lock (_locker)
                            {
                                featuresWriter.WriteLine(feature.Value);
                                RecordsWrote++;
                            }
                        }));
                }
            });

        Task.WaitAll(tasks.ToArray()); // Breaks
var tasks=newlist();
Parallel.ForEach(File.ReadLines(featuresLocation),s=>
{
var feature=CreateFeature;
if(feature.HasValue)
{
tasks.Add(Task.Factory.StartNew(()=>
{
锁(储物柜)
{
FeatureWriter.WriteLine(feature.Value);
RecordsWrite++;
}
}));
}
});
Task.WaitAll(tasks.ToArray());//打破
工作:

var tasks = new List<Task>();

Parallel.ForEach(File.ReadLines(featuresLocation), s =>
            {
                var feature = CreateFeature(s);
                if (feature.HasValue)
                {
                    tasks.Add(Task.Factory.StartNew(() =>
                        {
                            lock (_locker)
                            {
                                featuresWriter.WriteLine(feature.Value);
                                RecordsWrote++;
                            }
                        }));
                }
            });

        Task.WaitAll(tasks.Where(x => x != null).ToArray()); // Works
var tasks=newlist();
Parallel.ForEach(File.ReadLines(featuresLocation),s=>
{
var feature=CreateFeature;
if(feature.HasValue)
{
tasks.Add(Task.Factory.StartNew(()=>
{
锁(储物柜)
{
FeatureWriter.WriteLine(feature.Value);
RecordsWrite++;
}
}));
}
});
Task.WaitAll(tasks.Where(x=>x!=null).ToArray());//作品
var tasks=new List();
平行。ForEach(
{   
任务。添加(…);
});
使用
列出任务
不是线程安全的。您将看到
null
元素不应该出现在这些元素中,但运行时间稍长,您可能还会看到其他症状和异常。该行为未定义


保护对
任务的访问
,将其替换为
ConcurrentBag
,或者,根据我的选择,完全放弃这些任务。您从Parallel.ForEach()中获得了足够的并行性您看到了一个跨线程问题

此代码块访问非线程安全的
列表
,这可能导致不可预测和非确定性错误:

tasks.Add(Task.Factory.StartNew(() =>
    {
         ...
    }));
您需要锁定任务。添加呼叫:

lock(tasks)
{
    tasks.Add(Task.Factory.StartNew(() =>
      {
        ...
      }));
}

tasks变量的代码在哪里?我已经改变了问题,tasks变量与foreach在同一范围内,waitall启动在lock()内执行所有操作的任务并不是最理想的,特别是因为调用代码已经在foreach中。我会放弃这些任务。我不明白为什么要在并行循环中创建任务?不能同步吗?谢谢Sriram,这很有意义。。创建一个要写入文件的任务并没有给我带来任何好处:)
lock(tasks)
{
    tasks.Add(Task.Factory.StartNew(() =>
      {
        ...
      }));
}