I use a BackgroundWorker and do this:
private void loadNewAsyncToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Text = "RunWorkerAsync()";
backgroundWorkerLoading.RunWorkerAsync();
}
private void backgroundWorkerLoading_DoWork(object sender, DoWorkEventArgs e)
{
UnsafeThreadMethod("hello");
EvenUnsaferThreadMethod();
}
And now the two methods.
private void UnsafeThreadMethod(string text)
{
toolStripLabelRssFeedData.Text = text;
}
private void EvenUnsaferThreadMethod()
{
panelLoading.Visible = true;
}
I don’t understand why UnsafeThreadMethod doesn’t throw the following exception but EvenUnsaferThreadMethod does.
Cross-thread operation not valid: Control ‘panelLoading’ accessed from a thread other than the > thread it was created on.
According to the message it’s because toolStripLabelRssFeedData was created on the same thread but it wasn’t.
I thought that I can’t call controls created by the main thread and have to use the ProgressChanged event. What’s going on?
And I have a second question. What is the advantage of doing it like this when I can use ProgressChanged? What should I do?
private void EvenUnsaferThreadMethod()
{
if (panelLoading.InvokeRequired)
{
panelLoading.Invoke(new MethodInvoker(() => { EvenUnsaferThreadMethod(); }));
}
else
{
panelLoading.Visible = true;
}
}
To the first question:
the cross-thread exception is deliberately thrown in Debug mode. This means there is (conditional) code checking on InvokeRequired built into most of the GUI controls. Like the Panel.
Apparently the ToolstripLabel does not make this check. Since it does not derive from Control that could be because it is outside the scope of this safety net.
Since the standard disclaimer “Any instance members are not guaranteed to be thread safe” applies to the ToolstripLabel I would just go with the normal InvokeRequired logic when setting the Text.