Problem with thread changing UI

T

Trecius

Hello, Newsgroupians:

I have a question regarding threads changing the UI of a form. I have an
external device that sends signals to my application by using their library.
To do this, all I need to do is set the event that handles the incoming data.

public class Reader
{
private WeightReader m_reader;
...
public Reader()
{
this.m_reader.ResponseEvent += new
WeightReader.Response(this.ReceiveData);
}
public void ReceiveData(WeightEventArgs args)
{
...
}
}


Because ReceiveData is being called from an external thread, I do the
following before my program is initialized...

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

To make a long story short, in my ReceiveData(), I check the arguments that
come in and change my UI accordingly. I can set the text of a control
without any problem; however, if at any time a control needs to have its
Visible property set, the program just hangs. How can I get around this?

Here's a sample application that I have written; it only has a button and a
textbox. Initially, the textbox's Visible property is set to false when
intialized. Overall, this small application indicates the problem I am
having that an external thread cannot set the Visible property of a control;
however, it has the ability to set the text of a control. Why's this?

public partial class TempFrm : Form
{
public TempFrm()
{
InitializeComponent();

this.button1.Click += new EventHandler(button1_Click);
}

void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread th = new System.Threading.Thread(new
System.Threading.ThreadStart(this.Temp));
th.Start();
}

void Temp()
{
this.textBox1.Visible = true; // This does not work
//this.textBox1.Text = "Hello"; // This works if textBox1 is INITIALLY
visible
}
}

Thank you, all.


Trecius
 
J

Jon Skeet [C# MVP]

Because ReceiveData is being called from an external thread, I do the
following before my program is initialized...

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

Don't do that. It's the programmatic equivalent of covering your ears
and saying "I can't hear you!" when someone tells you off. You should
use Control.Invoke/BeginInvoke instead, or a BackgroundWorker.

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

Ciaran O''Donnell

You should call the Invoke method on a control to update it when not on the
thread that created it. You need to make a method like
void SetControlProperties(){.....}
and then a Delegate like:
Delegate void SetControlPropertiesDelegate();
Then do myControl.Invoke(new
SetControlPropertiesDelegate(SetControlProperties);

That will then call that function on the thread that created the control. If
you might not be on a different thread, you can call check
myControl.InvokeRequired to see if you need to do that.

Search the MSDN for help on it.
 

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