Threading: UI update from another namespace.

  • Thread starter Thread starter Brent
  • Start date Start date
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
 
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.
 
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
 
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
 
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?
 
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
 
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.
 
Back
Top