Threading: UI update from another namespace.

B

Brent

I'm really new to threading.

Imagine you create a thread like this:

public MainForm()
{

InitializeComponent();

Thread trd = new Thread(new ThreadStart(this.threadControl));
trd.IsBackground = true;
trd.Start();

}

public void threadControl()
{
classInAnotherNamespace run = new classInAnotherNamespace ();

run.longMethod();
}

How do I send back messages back to the UI from run.longMethod()? For
instance, I might want to let the user know that the routine is
"Beginning procedure 1" or "Ending procedure 1," etc.

I'd sure appreciate any tips.

Thanks!

--Brent
 
J

Jon Skeet [C# MVP]

I'm really new to threading.

Imagine you create a thread like this:

public MainForm()
{

InitializeComponent();

Thread trd = new Thread(new ThreadStart(this.threadControl));
trd.IsBackground = true;
trd.Start();

}

public void threadControl()
{
classInAnotherNamespace run = new classInAnotherNamespace ();

run.longMethod();
}

How do I send back messages back to the UI from run.longMethod()? For
instance, I might want to let the user know that the routine is
"Beginning procedure 1" or "Ending procedure 1," etc.

See http://www.pobox.com/~skeet/csharp/threads/winforms.shtml

Namespaces are irrelevant here - the key is not to try to update the UI
from a different thread. It doesn't matter which namespace you're in.
 
P

Pete Davis

Well, first of all, threading has nothing to do with namespaces. A thread
could care less about what namespace another thread is in. It simply matters
that they're separate threads.

Namespaces are largely just a convenience of organizing for humans to better
understand the code.

As for how to communicate back, there are a number of ways. One simple (and
not terribly elegant way), assuming you only have one instance of MainForm
is to store that instance in a public static field. For example:

public class MainForm
{
public static _mainFormInstance;

public MainForm()
{
_mainFormInstance = this;
...
}

public void ThreadNotification(string message)
{
Console.WriteLine("Thread sent following message: " + message);
}
}


Then from the thread, simply do:

MainForm._mainFormInstance.ThreadNotification("This is a message");

Pete
 
B

Brent

Thanks for your replies!

This example is instructive, but I'm still having a hard time wrapping
my head around getting the message back to the main form. The example
uses a MethodInvoker to call an update function within the same
namespace, which then updates a control or what-have-you on the form,
also in the same namespace. But if I do something similar, say, invoking
(in Namespace2) ...

public void output(string value)
{
richTextBox1.AppendText(value + "\n");

}

.... the compiler complains that richTextBox1 doesn't exist. Which it
doesn't, not in Namespace2.

Alternately, if (after referencing in Namespace2 the namespace where
MainForm is located) I try ...

public void output(string value)
{

MainForm.richTextBox1.AppendText(value + "\n");

}

....the compiler tells me I can't access richTextBox1 because of its
protection level.

I must be having some kind of structural problem here.

I do appreciate your help.

Thanks!

--Brent
 
J

Jon Skeet [C# MVP]

Thanks for your replies!

This example is instructive, but I'm still having a hard time wrapping
my head around getting the message back to the main form. The example
uses a MethodInvoker to call an update function within the same
namespace, which then updates a control or what-have-you on the form,
also in the same namespace. But if I do something similar, say, invoking
(in Namespace2) ...

Please, ignore the whole namespace issue. It's a red herring.
public void output(string value)
{
richTextBox1.AppendText(value + "\n");

}

... the compiler complains that richTextBox1 doesn't exist. Which it
doesn't, not in Namespace2.

The namespace isn't important. What's important is that it doesn't
exist in your *class*. You need to give it a reference to that form
somehow - eg by passing it into the constructor of your other class,
which would obviously have to be modified appropriately.
Alternately, if (after referencing in Namespace2 the namespace where
MainForm is located) I try ...

public void output(string value)
{

MainForm.richTextBox1.AppendText(value + "\n");

}

...the compiler tells me I can't access richTextBox1 because of its
protection level.

So I should hope. I'd also hope that richTextBox1 isn't a static member
- what would you do if you had two MainForms visible?
 
B

Brent

That's the push I needed! I've got the initial code working now by
passing a RichTextBox reference from namespace1 to namespace2.

Thanks!

--Brent

<snip>

You need to give it a reference to that form
 
J

Jon Skeet [C# MVP]

That's the push I needed! I've got the initial code working now by
passing a RichTextBox reference from namespace1 to namespace2.

No, it's passing it from one *class* to another. As I keep saying,
namespaces are entirely irrelevant here.
 

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