从另一个线程获取richtextbox.text

时间:2014-01-10 14:58:21

标签: c# multithreading backgroundworker

我无法相信以前没有问过这个问题,但我在这里找不到参考资料。对不起,如果我错过了!!从线程更新rtb.Text有很多,但很少或没有获取rtb.Text。

我需要从另一个线程的UI线程上的richtextbox获取文本值,然后才能遍历同一个richtextbox的每一行。

我猜Invokes和Delegates是必需的,但是如何制作它们?

作为示例,如果代码位于同一个线程中,则代码类似于:

private void checkRtbEntries()
{
    if (rtb.Text != "")
    {
        foreach (string textLine in rtb.Lines)
        {
            // do some things in the background thread 
            // based on the rtb line content...
        }
    }
}

但是,在Backgroundworker线程中调用checkRtbEntries(),并且rtb在UI线程中,因此抛出了无效的跨线程操作。

2 个答案:

答案 0 :(得分:3)

运行BackgroundWorker线程时,可以选择将参数传递给它,另一个线程可以引用该参数并使用:

myWorker.RunWorkerAsync(rtb.Text);

DoWork事件中,将参数强制转换为字符串并对其执行操作。

var myRtbText = e.Argument.ToString();

这样,您的后台线程实际上从未触及UI线程。

如果您需要在后台工作人员运行时对主线程上的元素进行更改,则需要使用ProgressChanged事件。

由于您没有RichTextBox事件中DoWork的引用(只是Text属性的内容),因此您实际上无法调用{{1原始文本框上的属性。

你应该能够很容易地模拟它(实际的Lines属性测试“\ r”,“\ r \ n”和“\ n”,但Lines应该采取关心为你解决这个问题):

Environment.NewLine

(如果要忽略空行,请使用StringSplitOptions.RemoveEmptyEntries。)

答案 1 :(得分:1)

这是从后台跳转到UI线程(对于每个控件)的常用方法

 private delegate void checkRichTextBoxDelegate(); 
 private void checkRtbEntries() 
 { 
     if (this.rtb.InvokeRequired) 
     { 
         checkRichTextBoxDelegate checkEntries = new checkRichTextBoxDelegate(checkRtbEntries); 
         this.Invoke(checkRtbEntries); 
     } 
     else 
     { 
         .... do your work on the RichTextBox, you are on the UI thread
     } 
 }