I am working on a file listener (for txt files) using FileSystemWatcher and want to append all new lines to a RichTextBox. Format new text to rich text needs alot of cpu power, so I decided to use a BackgroundWorker for this.
The program is still working, but form hangs when I lock MS Windows and relogin. Seems as BackgroundWorker thread is blocking the UI thread. There is no other effect of using BeginInvoke instead of Invoke for AppendText to RichTextBox.
When I pass the unformatted text to e.Result of bw_DoWork everything is working fine (no blocking threads). The temporary RichTextBox is not attached to the main form. How can I solve the “hang” problem?
Logic before code sample: FileSystemWatcher event Changed starts 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();
}
Note: These are only the code parts to understand the problem. It’s not complete.
The
RichTextBoxcannot be created or manipulated on the worker thread. You MUST do it on the UI thread.The
bw_RunWorkerCompletedis run on the UI thread, soBeginInvokeis not required.You need to move all the code after
ReadFromFileintobw_RunWorkerCompletedand you will not need a tempRichTextBoxanymore.