从另一个线程获取richtextbox.text

问题描述 投票:0回答:2

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

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

我想Invokes和代表是必需的,但如何制作它们?

作为一个例子,代码,如果它在同一个线程中,将是这样的:

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...
        }
    }
}

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

c# multithreading backgroundworker
2个回答
3
投票

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

myWorker.RunWorkerAsync(rtb.Text);

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

var myRtbText = e.Argument.ToString();

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

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

由于RichTextBox事件中没有对DoWork的引用(只是其Text属性的内容),因此您无法在原始文本框中调用Lines属性。

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

var allLines
    = myRtbText.Split(new[] {Environment.NewLine}, StringSplitOptions.None);

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


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
     } 
 } 
© www.soinside.com 2019 - 2024. All rights reserved.