Parallel.ForEach和ListView控件

时间:2011-01-19 04:21:12

标签: c# .net .net-4.0

我遇到了使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;

3 个答案:

答案 0 :(得分:3)

你正在做的2个问题。

1)使用此特定代码,您尝试从不允许的后台线程修改UI 2)无论如何,这种情况不适合并行化,因为你的性能是“I / O绑定”到单个硬盘驱动器。如果你想加快加载时间,将文件拆分到多个硬盘上,然后并行化可能是值得的

请参阅Is Parallel File.Read Faster than Sequential Read?

答案 1 :(得分:0)

您不允许从非UI线程更新UI,Parallel.ForEach中的线程显然是这样。而是使用Invoke方法设置Text的{​​{1}}并调用rtbMessages

答案 2 :(得分:0)

我正在体验这个问题的dejavu ......无论如何,请看一下这篇博客文章。这很符合我的口味,但确实是你想要实现的 - 在使用新的.NET 4并行机制处理并发集合时更新UI。虽然不是ForEach而是Task。

http://blogs.msdn.com/b/csharpfaq/archive/2010/06/18/parallel-programming-task-schedulers-and-synchronization-context.aspx