PLINQ + LINQ = NRE?

时间:2015-04-07 09:21:53

标签: c# linq nullreferenceexception plinq

运行下面的代码时,随机NRE的原因是什么?鉴于results已初始化,如何将lambda中的t作为null

var results = new List<Result>();

for (int i = 0; i < 100; i++)
{
    Parallel.For((index) =>
        {
            results.Add(Result.Create(...));    
        });

    results = results.Where(t => t.IsValid).ToList(); // NRE here due to t is null!

}

1 个答案:

答案 0 :(得分:4)

List<>不是线程安全的。您正在添加来自多个线程的元素。如果你真的想用它:

lock (results)
{
    results.Add(Result.Create(...));
}

请注意,您的示例是错误的......编译和运行的内容将是:

var results = new List<Result>();

Parallel.For(0, 100, index =>
{
    lock (results)
    {
        results.Add(Result.Create(...));
    }
});

results = results.Where(t => t.IsValid).ToList(); // NRE here due to t is null!

或更好

var results = new List<Result>();

Parallel.For(0, 100, index =>
{
    var result = Result.Create(...);

    lock (results)
    {
        results.Add(result);
    }
});

results = results.Where(t => t.IsValid).ToList(); // NRE here due to t is null!

这样result创建就不会阻止List<>写入:-)否则代码就没用了,它将按顺序执行。