update UI from Thread - control.invoke or controlinvoker?

This is a CF 1.0 application. I need to load an image in a background thread and use it in the UI thread. I'm a little confused. There have been tutorials that have the background thread write to a public variable in the Form, then Control.Invoke when they're finished to have the UI thread update the form. (No locking). This looks very simple, I'd like to do it this way. The following is the way the tutorial described - the thread writes directly to the Form, but not to any control on the form. Is that "legal"

public class MainFrame : Form
{
private int progressBar1Status = 0;

public MainFrame()
{
InitializeComponent();
DoThreading();
}

public void DoThreading()
{
Thread t = new Thread(
new ThreadStart(UpdateProgessBar));
t.Start();
}

public void UpdateProgessBar()
{
int j = 0;
while (j < 100)
{
progressBar1Status = j;
progressBar1.Invoke(new EventHandler(WorkerUpdate));
j++;
}
}
public void WorkerUpdate(object sender, EventArgs e)
{
progressBar1.Value = progressBar1Status;
progressBar1.Update();
}



Then there are some tutorials on this ControlInvoker that state you shouldn't write to the main Form, but pass the data to it using this ControlInvoker class.




Answer this question

update UI from Thread - control.invoke or controlinvoker?

  • Drake1500

    You can access anything on a form (and in any other class) without using Invoke as long as you don't touch any controls, directly or indirectly. In some cases locking might be needed, but it’s not related to Invoke.

    int foo;

    TextBox box;

    foo =10; // OK from the thread.

    box.Text = "Will hang!"; // No can do from the thread.



  • HuWu

    Correct, you can't touch the Form (which is also Control) from another thread. However, these strings and memory streams and other member variables you’ve added are not part of the Form, they are part of your class which inherits from the Form. So there's no need to use Control.Invoke() to access them. There’s no harm in doing that though, except for code complexity and performance impact.

    In some cases member variable can be “connected” to controls (e.g. you have member DataTable bound to the DataGrid). In that case you might need to use Control.Invoke(). In the DataTable/DataGrid example you can read from DataTable freely, but you have to use Control.Invoke() to add/delete/change rows.



  • Vesigo

    Thanks Ilya,

    Just about everything I've read stated never to touch the controls from a thread. They never said the Form itself was fair game. I've setup some variables in the form (strings, memory streams, etc.) to write to from the child threads, then Invoke to update the controls using that information. It seems to work well.

    Thanks


  • update UI from Thread - control.invoke or controlinvoker?