C# parallel.for循环上的UI非定位问题
我正在使用任务并行库在c#上构建一个记事本应用程序,但当我应用搜索功能时,整个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) =>
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;
}