【发布时间】:2015-12-08 10:28:11
【问题描述】:
我想从另一个线程调用RichTextBox.Find()。我怎样才能做到这一点?
RichTextBox 位于我在表单中使用的UserControl 中。
我想从另一个线程更新它。我能够使用Invoke 更改其属性。但不知道如何从我的线程中调用_ucResultRich.rchResult.Find(word, startIndex, RichTextBoxFinds.None);。
Thread thread=new Thread(thrHighlight);
thread.Start(e.RowIndex);
private void ThrHighlight(object obj)
{
string[] words = ucSearchControls.rdbExact.Checked
? new string[] { ucSearchControls.txtSearch.Text.Trim() }
: ucSearchControls.txtSearch.Text.Split(' ');
foreach (string word in words)
{
int startIndex = 0;
while (startIndex < _ucResultRich.rchResult.TextLength)
{
int wordStartIndex = _ucResultRich.rchResult.Find(word, startIndex, RichTextBoxFinds.None);
if (wordStartIndex != -1)
{
_ucResultRich.rchResult.SelectionStart = wordStartIndex;
_ucResultRich.rchResult.SelectionLength = word.Length;
_ucResultRich.rchResult.SelectionBackColor = Color.Yellow;
}
else
break;
startIndex += wordStartIndex + word.Length;
}
}
}
我该怎么做?
P.S:这是my first question 和@varocarbas cmets 的后续行动
【问题讨论】:
-
你为什么不能同时使用
Invoke? -
您的示例中的整个方法('ThrHighlight`)是纯 UI,因此应该在 UI 线程上运行。
-
我在这方面的想法(包括旧帖子):我说你错误地使用了后台工作程序,如果使用不当,最好不要使用它。但我确实认为,对于 2 线程情况(GUI + 长计算,理想情况下与 GUI 元素交互尽可能少,导致 GUI 冻结的原因),backgroundworker 确实提供了最佳解决方案(非常直观)。这就是为什么我花了一些时间编写清晰的代码来向您(和未来的读者)展示如何在这种情况下正确使用它。无论如何,正如伊万在上面的评论中正确指出的那样......
-
... 你最好只依赖 1 个线程来实现这个特定的实现,因为一切都发生在 GUI 线程中(正如你可以通过分析我的代码来确认的那样,它在 GUI 和后台工作线程之间系统地移动= 无论如何都不会发生冻结,这恰好发生在长时间不访问 GUI 线程时)。需要 2 个线程的场景?当分析完全不影响 GUI 控件时(例如,读取文件;下载文件;或正在分析文本,但不依赖 RichTextBox 扩展方法)。
标签: c# multithreading winforms invoke