Communicating Between Threads

J

jehugaleahsa

Hello:

I want to have a class that sends messages to a textbox. However, I
want the message sender to be in a different thread than the message
displayer, so users can scroll through the messages.

How do I communicate between these threads?

Thanks,
Travis
 
N

Nicholas Paldino [.NET/C# MVP]

Travis,

You will have make an implementation of ISynchronizeInvoke available to
the thread so that you can call the Invoke method on it, passing a delegate
to be executed on the UI thread. The Control class implements
ISynchronizeInvoke, so you can use any control which was created on the UI
thread.

Basically, assume your textbox is visible to the method that is being
executed on the thread, you could do this:

public void ThreadEntryPoint()
{
// Do work here.

// Update the textbox.
statusTextbox.Invoke(new Action<T>(UpdateStatus), new object[]{ "Updated
status." });
}

private void UpdateStatus(string status)
{
statusTextbox.Text = status;
}
 
D

Daniel Bass

You need to hook into the textbox thread, as, by the sounds of it, you've
figured out already.
Take a look at the code below for how to do this using Invoke...

Cheers.
Dan.


private object listLock = new object();
public delegate void AddTextDelegate(string myText);

/// <summary>
/// Adds the text to a text box
/// </summary>
/// <param name="fi">The fi.</param>
public void AddText(string myText)
{
if (_myTextBox == null)
return;

if (_myTextBox.InvokeRequired)
{
_myTextBox.Invoke(new AddTextDelegate(AddText), new object[]
{myText});
}
else
{
lock (listLock)
{
_myTextBox.Text = text
}

}
}
 
P

Peter Duniho

[...]
public void ThreadEntryPoint()
{
// Do work here.

// Update the textbox.
statusTextbox.Invoke(new Action<T>(UpdateStatus),
new object[]{ "Updated status." });
}

I think instead of "Action<T>" you meant to write "Action<string>". Right?

Personally, I prefer the anonymous delegate method unless there's a
specific need for the method being invoked to be reused elsewhere (e.g.
it's more complicated than just a single assignment and you do the same
thing from other places in the code):

statusTextbox.Invoke(new MethodInvoker(delegate() { statusTextbox.Text
= "Updated status"; }));

Of course, the string "Updated status" can be replaced by whatever is
suitable in the context, like a variable referring to a string, or the
result of a call to some variable's ToString() method, or whatever.

And of course, either way is fine. There's nothing wrong with using a
non-anonymous delegate method.

Pete
 
P

Peter Duniho

[...]
public void AddText(string myText)
{
if (_myTextBox == null)
return;

if (_myTextBox.InvokeRequired)
{
_myTextBox.Invoke(new AddTextDelegate(AddText), new
object[]
{myText});
}
else
{
lock (listLock)
{
_myTextBox.Text = text
}

}

Why the "lock()" statement? The whole point of using Invoke() is that you
are not allowed to operate on the Control from other threads. The check
for InvokeRequired guarantees that only one thread, the Control instance's
owning thread, will ever execute the code within the "lock()", so there
should never be any other thread that might take the lock. For sure, no
other thread can take the lock using the AddText() method, and it should
not be taking the lock from any other code either.

Pete
 
N

Nicholas Paldino [.NET/C# MVP]

Yes, Action<string> is what was meant.

It doesn't matter either way, like you said, but I felt that it wasn't a
bad idea to encapsulate the logic for updating the status. However, if
that's all that needs to be done, then it really doesn't matter.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

[...]
public void ThreadEntryPoint()
{
// Do work here.

// Update the textbox.
statusTextbox.Invoke(new Action<T>(UpdateStatus),
new object[]{ "Updated status." });
}

I think instead of "Action<T>" you meant to write "Action<string>". Right?

Personally, I prefer the anonymous delegate method unless there's a
specific need for the method being invoked to be reused elsewhere (e.g.
it's more complicated than just a single assignment and you do the same
thing from other places in the code):

statusTextbox.Invoke(new MethodInvoker(delegate() { statusTextbox.Text
= "Updated status"; }));

Of course, the string "Updated status" can be replaced by whatever is
suitable in the context, like a variable referring to a string, or the
result of a call to some variable's ToString() method, or whatever.

And of course, either way is fine. There's nothing wrong with using a
non-anonymous delegate method.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top