我遇到了使Parallel.ForEach正常工作的问题。我有一个listview控件,可以将文件内容或多个文件内容(每个文件代表一个日志文件)加载到richtextbox中。如果它全部使用Foreach循环,但决定在加载100多个文件时并行操作会减少加载时间。
这是我用于foreach循环的代码块。如何让Parallel.Foreach工作?
//Set cursor to WaitCursor Style
this.Cursor = Cursors.WaitCursor;
//Clear Messages RichTexBox
this.rtbMessages.Clear();
//Loop through each selected file
foreach (ListViewItem Item in lvMessageFiles.Items)
{
//Check if item is selected in the listview
if (Item.Selected && rtbMessages.TextLength < rtbMessages.MaxLength)
{
//Get Path to message file
filename = String.Format("{0}\\Data\\Log\\{1}.log", Global.AppPath, Item.SubItems[0].Text);
//Set Timeline Events calendar to selected items created date
cvTimeline.ShowDate(Convert.ToDateTime(lvMessageFiles.SelectedItems[0].SubItems[2].Text));
//Check if file exists
if (File.Exists(filename))
{
//streamreader to read the file
reader = new StreamReader(filename);
//to copy the read content in to richtextbox
string MessageContents = String.Format("{0}\n{1}\n", ("file:///" + filename.Replace(" ", "%20").Replace("\\", "/")), reader.ReadToEnd());
rtbMessages.Text += MessageContents;
// closing streamreader
reader.Close();
}
}
}
//Set cursor to WaitCursor Style
this.Cursor = Cursors.Default;
答案 0 :(得分:3)
你正在做的2个问题。
1)使用此特定代码,您尝试从不允许的后台线程修改UI 2)无论如何,这种情况不适合并行化,因为你的性能是“I / O绑定”到单个硬盘驱动器。如果你想加快加载时间,将文件拆分到多个硬盘上,然后并行化可能是值得的
答案 1 :(得分:0)
您不允许从非UI线程更新UI,Parallel.ForEach
中的线程显然是这样。而是使用Invoke方法设置Text
的{{1}}并调用rtbMessages
答案 2 :(得分:0)
我正在体验这个问题的dejavu ......无论如何,请看一下这篇博客文章。这很符合我的口味,但确实是你想要实现的 - 在使用新的.NET 4并行机制处理并发集合时更新UI。虽然不是ForEach而是Task。