PLINQ + LINQ = NRE?
PLINQ + LINQ = NRE?
运行以下代码出现随机 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!
}
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<>
的写入 :-) 否则代码是无用的,它将被顺序执行。
运行以下代码出现随机 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!
}
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<>
的写入 :-) 否则代码是无用的,它将被顺序执行。