Chr*_*nte 21 c# parallel-processing multithreading thread-safety
基本上,我正在使用这个:
var data = input.AsParallel();
List<String> output = new List<String>();
Parallel.ForEach<String>(data, line => {
String outputLine = "";
// ** Do something with "line" and store result in "outputLine" **
// Additionally, there are some this.Invoke statements for updating UI
output.Add(outputLine);
});
Run Code Online (Sandbox Code Playgroud)
输入是一个List<String>对象.该ForEach()语句对每个值进行一些处理,更新UI,并将结果添加到output List.这有什么本质上的错误吗?
笔记:
更新:
根据我得到的反馈,我lock在output.Add声明中添加了一个手册,以及UI更新代码.
Mar*_*ell 30
是; List<T>是不是线程安全的,所以从任意线程(很可能同时)ad-hoc添加它是注定的.您应该使用线程安全列表,或手动添加锁定.或者也许有一个Parallel.ToList.
此外,如果重要:插入订单将无法保证.
不过这个版本是安全的:
var output = new string[data.Count];
Parallel.ForEach<String>(data, (line,state,index) =>
{
String outputLine = index.ToString();
// ** Do something with "line" and store result in "outputLine" **
// Additionally, there are some this.Invoke statements for updating UI
output[index] = outputLine;
});
Run Code Online (Sandbox Code Playgroud)
这里我们index用来为每个并行调用更新一个不同的数组索引.
Eri*_*ert 11
这有什么本质上的错误吗?
是的,一切.这些都不安全.列表并不安全地同时更新多个线程,并且您无法从UI线程以外的任何线程更新UI.