C# parallel.for循环上的UI非定位问题

C# parallel.for循环上的UI非定位问题,c#,winforms,task-parallel-library,C#,Winforms,Task Parallel Library,我正在使用任务并行库在c#上构建一个记事本应用程序,但当我应用搜索功能时,整个UI都卡住了。我尝试调用该方法,但仍然没有帮助。以下是搜索功能 private void toolStripButton1_Click_1(object sender, EventArgs e) { Parallel.For(0, GetRichTextBox().Text.LastIndexOf(toolStripTextBox1.Text) + 1, (int i) =>

我正在使用任务并行库在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;
    }

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

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


某种修复: 使用System.Linq; 使用System.Text.RegularExpressions; 私有无效工具条带按钮1\u单击1(对象发送者,事件参数e) { //只获取一次文本框。 var textBox=GetRichTextBox(); //仅设置一次选择颜色。 textBox.SelectionBackColor=Color.Orange; //获取要查找的文本 var textToFind=toolStripTextBox1.Text; //获取要搜索的文本 var completeText=textBox.Text; //转义要查找的文本,因为我们正在使用正则表达式查找它们 var escapedTextToFind=Regex.Escape(textToFind); //在完整文本中查找搜索文本的所有索引 var index=Regex.Matches(completeText、escapedTextToFind) 第()类 .选择(m=>m.Index); //选择文本框中找到的每个索引 foreach(var selectionStartIndex in indexes) { textBox.Select(selectionStartIndex,textToFind.Length); } } //不需要调用,因为我们希望在UI线程上执行UI操作 公共RichTextBox GetRichTextBox() { //您可以使用空条件运算符,而不是空检查 //见:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators 返回tabControl1?,选择Tab?.Controls?[0]作为RichTextBox; }
我怀疑这是否有效,因为我相信您可以同时选择多个文本。因为大部分代码都在UI上完成,所以您应该在UI上完成所有的工作。但是如果文本量非常大,并且UI仍然挂起,您可以同时使用粗体部分。但我认为这太过分了。

我有什么办法解决这个问题?抱歉,我对编程相当陌生。我猜您希望在
GetRichTextBox()
中进行选择,并且需要选择的文本应该是
toolStripTextBox1。text
?Parallel。因为它本身不会在另一个线程中运行。此外,尝试在后台执行UI工作几乎总是需要调用在UI线程上运行的
Invoke
,因此在性能方面没有任何好处。我知道,但这是我的任务的一个要求:/ using System.Linq; using System.Text.RegularExpressions; private void toolStripButton1_Click_1(object sender, EventArgs e) { // Get the textbox just once. var textBox = GetRichTextBox(); // Set the selection color also just once. textBox.SelectionBackColor = Color.Orange; // get the text to find var textToFind = toolStripTextBox1.Text; // get the text to search in var completeText = textBox.Text; // escape the text to find because we are using regex to find them var escapedTextToFind = Regex.Escape(textToFind); // find all the index of the search text int the complete text var indexes = Regex.Matches(completeText, escapedTextToFind) .OfType<Match>() .Select(m => m.Index); // select every found index in the textbox foreach (var selectionStartIndex in indexes) { textBox.Select(selectionStartIndex, textToFind.Length); } } // No needs for invoke, since we want to do UI stuff on the UI thread public RichTextBox GetRichTextBox() { // instead of null checks, you can use the null conditional operators // see: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators return tabControl1?.SelectedTab?.Controls?[0] as RichTextBox; }