0

我正在使用文件侦听器(用于 txt 文件)FileSystemWatcher并希望将所有新行附加到RichTextBox. 将新文本格式化为富文本需要大量的 cpu 能力,所以我决定为此使用 BackgroundWorker。

该程序仍在运行,但当我锁定 MS Windows 并重新登录时,表单会挂起。似乎 BackgroundWorker 线程正在阻塞 UI 线程。BeginInvoke使用代替Invokefor AppendText 到 RichTextBox没有其他效果。

当我将未格式化的文本传递给e.Result一切bw_DoWork正常时(没有阻塞线程)。临时 RichTextBox 未附加到主窗体。如何解决“挂起”问题?

代码示例之前的逻辑:FileSystemWatcher事件Changed开始BackgroundWorker.RunWorkerAsync

StringBuilder unformattedText;

private void bw_DoWork( object sender, DoWorkEventArgs e )
{
    // Write all new lines for this file to 
    // StringBuilder variable unformattedText
    ReadFromFile (...)

    // Need a temporary RichTextBox to create new formatted text
    RichTextBox tempRtb = new RichTextBox();

    // Split new unformatted text with regex, format some tokens 
    // and append each to temporary RichTextBox tempRtb
    HighlightWords( tempRtb, unformattedText );

    e.Result = tempRtb.Rtf;
}

private void bw_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e )
{
    string rtfText = e.Result as string;

    // Append text to main RichTextBox 
    if (rtb.InvokeRequired)
    {
            rtb.BeginInvoke(
                new MethodInvoker( delegate
                {
                    AppendRichText( rtb, rtfText );
                } ) );
    }
    else
    { 
        AppendRichText( rtb, rtfText );
    }
}

private void AppendRichText(RichTextBox rtb, string text)
{
    // Append formatted text at the end of the RichTextBox
    rtb.Select( rtb.TextLength, 0 );
    rtb.SelectedRtf = text;

    rtb.ScrollToCaret();
}

注意:这些只是理解问题的代码部分。它不完整。

4

1 回答 1

0

RichTextBox不能在工作线程上创建或操作。您必须在 UI 线程上执行此操作。

bw_RunWorkerCompletedUI 线程上运行,因此BeginInvoke不是必需的。

您需要将所有代码ReadFromFile移入之后bw_RunWorkerCompleted,您将不再需要临时文件RichTextBox

于 2013-01-14T19:01:39.700 回答