【问题标题】:UI Unresposive issue on parallel.for loopparallel.for 循环上的 UI 无响应问题
【发布时间】:2018-05-18 21:55:37
【问题描述】:

我正在使用任务并行库在 c# 上构建一个记事本应用程序,但是当我应用搜索功能时,整个 UI 都会卡住。我尝试调用该方法,但仍然没有帮助。以下是搜索功能。

private void toolStripButton1_Click_1(object sender, EventArgs e)
    {

        Parallel.For(0, GetRichTextBox().Text.LastIndexOf(toolStripTextBox1.Text) + 1, (int i) =>
        {
            GetRichTextBox().Find(toolStripTextBox1.Text, i, GetRichTextBox().TextLength, RichTextBoxFinds.None);
            GetRichTextBox().SelectionBackColor = Color.Orange;
            i = GetRichTextBox().Text.IndexOf(toolStripTextBox1.Text, i) + 1;
        });
    }

以下代码是GetRichTextBox方法。

 public  RichTextBox GetRichTextBox()
    {
        Invoke(new MethodInvoker(delegate ()
        {
        TabPage tp = tabControl1.SelectedTab;
        if(tp!= null)
        {
            rtb = tp.Controls[0] as RichTextBox;
        }

        }));
        return rtb;
    }

【问题讨论】:

  • Parallel.For 本身不在另一个线程中运行。此外,尝试在后台执行 UI 工作几乎总是涉及调用在 UI 线程上运行的 Invoke,因此在性能方面没有任何收获。
  • 我知道,但这是我的任务的要求:/

标签: c# winforms task-parallel-library


【解决方案1】:

代码:GetRichTextBox() 在 UI 线程上被调用(通过使用 Invoke(...) 方法)。

在并行 for 循环的主体中,您调用该方法 4 次。因此,大部分并行体都在 UI 线程上调用,从而使您的应用程序无响应。


某种修复:

使用 System.Linq; 使用 System.Text.RegularExpressions; private void toolStripButton1_Click_1(对象发送者,EventArgs e) { // 只获取一次文本框。 var textBox = GetRichTextBox(); // 也只设置一次选择颜色。 textBox.SelectionBackColor = 颜色.Orange; // 获取要查找的文本 var textToFind = toolStripTextBox1.Text; // 获取要搜索的文本 var completeText = textBox.Text; // 转义要查找的文本,因为我们正在使用正则表达式来查找它们 var escapedTextToFind = Regex.Escape(textToFind); // 在全文中查找搜索文本的所有索引 var 索引 = Regex.Matches(completeText, escapedTextToFind) .OfType() .Select(m => m.Index); // 选择文本框中所有找到的索引 foreach(索引中的变量 selectionStartIndex) { textBox.Select(selectionStartIndex, textToFind.Length); } } // 不需要调用,因为我们想在 UI 线程上做 UI 的事情 公共 RichTextBox GetRichTextBox() { // 代替空检查,你可以使用空条件运算符 // 参见:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators 返回 tabControl1?.SelectedTab?.Controls?[0] 作为 RichTextBox; }

我怀疑这是否可行,因为我相信您可以同时选择多个文本。因为大部分代码都在 UI 上执行,所以您应该在 UI 上执行所有这些代码。但如果文本量很大,UI 还是挂起,你可以并行加粗部分。但我认为这是矫枉过正。

【讨论】:

  • 我对这个问题有什么解决方案?抱歉,我对编程很陌生。
  • 我猜你希望在GetRichTextBox()中进行选择是否正确,需要选择的文本应该是toolStripTextBox1.Text
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多