Re: Multithread writes to a Rich Text Box

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Ray,

I would address the issue of multithreading first. Since you are not
making this call on another thread, I would say to take out the call to
Invoke. In regards to the part that has:

delegate
{
// Code here.
}

You can take the delegate and the brackets away, and just call the code
directly, and it should work.

You should also probably take out the call to DoEvents, as it's just
pointless in this case.

As for the msgtype parameter changing (the colors and whatnot) if you
don't have a multithreaded program, then nothing should be changing this
once you get into your method.

Also, if msg is null, or blank, then you should look at the call stack
when this method is called to try and determine the path the code took to
make msg null. Parameters don't just disappear.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx

"Ray Mitchell" <RayMitchell_NOSPAM_@xxxxxxxxxxxxxxxxxx> wrote in message
news:DC727BC6-BAFE-4B9F-8AEC-41D7A1E15289@xxxxxxxxxxxxxxxx
Hello,

Sorry for the long-winded dissertation - but, I have an application where
I
need to write text to a rich text box using a common method, callable from
anywhere in my application. The color of the text will depend upon the
first
argument and the text will be contained in the second argumet. As far as
I
know, my application is not multithreaded - at least I don't knowingly
start
any other threads. Since I don't know what the heck I'm doing, I found an
application that did this type of thing and merely "borrowed" the code to
do
it. The code is shown below, with a couple of changes, which I will
describe.

My first question involves why the code is written using Invoke rather
than
just a simple method call? I do know that Invoke should (must?) be used
when
doing multithreading, but I wasn't aware I was doing any multithreading.
However, if I remove the Invoke "wrapper" from around the code it won't
even
compile - so I left the "wrapper" in place!

Second, notice that I have a test for the msg parameter being null. This
should never happen but it sometimes does. I've single stepped through it
and sometimes, although msg is not null just prior to entering the Invoke
block, it mysteriously becomes null when that block is entered.

The next issue is the color. Note that I am setting the color with
parameter "msgtype". Most of the time this also works fine. However,
once
in a while the parameter value and the font's color property are okay
right
up to the rtfTerminal.AppendText statement. But as that statement gets
executed both the parameter and the font property change and the text gets
printed in the wrong color. Sometimes this change occurs in the middle of
the string that's being printed.

The final issue is the jitter that accompanies the ScrollToCaret() method
if
the entire message is written as one string followed by a single call to
ScrollToCaret(). It makes no sense to me why doing it the way I have
done -
character at a time - should work differently, but it does. I think this
is
probably a separate issue from the previous two.

So, my final suspicion on this is that the code I "borrowed" probably has
some inherent philosophical problem that is currently beyond my knowledge.
Is there a more appropriate way to implement a common method to write to a
rich text box?

Thanks,
Ray



public void Log(LogMsgType msgtype, string msg)
{
rtfTerminal.Invoke(new EventHandler(delegate
{
rtfTerminal.SelectedText = string.Empty;
rtfTerminal.SelectionFont = new Font(rtfTerminal.SelectionFont,
FontStyle.Bold);
rtfTerminal.SelectionColor = LogMsgTypeColor[(int)msgtype];
rtfTerminal.Font = new Font(rtfTerminal.SelectionFont,
FontStyle.Bold);
if (msg != null)
{
// This loop prevents scrolling on every character, which
causes
jitter.
foreach (char ch in msg)
{
if (ch != '\r')
{
rtfTerminal.AppendText(ch.ToString());
if (ch == '\n')
rtfTerminal.ScrollToCaret();
}
}
Application.DoEvents();
}
else
rtfTerminal.AppendText("\n\n**** ERROR: NULL MESSAGE
****\n\n");
}
));
}



.



Relevant Pages

  • Re: Advise on Real-Time update to column control
    ... I think the problem should be the multithreading ... That is in .Net Framework, when using multi-thread, ... This is the multithreading invoking rule ... invoke, then use Control.BeginInvoke method to invoke this delegate. ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Re: Help in c pointers
    ... Neither pointer has been initialized, and both assignments invoke UB. ... there's a third instance of undefined behavior here - ... `msg' isn't a c-string so ...
    (comp.lang.c)
  • Re: Multithread writes to a Rich Text Box
    ... need to write text to a rich text box using a common method, ... My first question involves why the code is written using Invoke rather than ... doing multithreading, but I wasn't aware I was doing any multithreading. ... executed both the parameter and the font property change and the text gets ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Help in c pointers
    ... char * msg; ... Neither pointer has been initialized, and both assignments invoke UB. ... `msg' isn't a c-string so ...
    (comp.lang.c)