derekantrican derekantrican - 3 months ago 20
C# Question

Updating WinForms GUI async with anonymous method

I've got a Windows Forms application and I'm trying to update controls asynchrnoously, which - of course - led me to this question: How to update the GUI from another thread in C#?

After much Googling and trouble understanding how to implement the #1 answer, I instead turned to the 2nd answer: http://stackoverflow.com/a/661662/2246411

My code now looks like this:

private void showPicture(string name)
{
if (name == "")
{
if (!this.Created || (isNullOrEmpty(comboBoxRepresentative) && isNullOrEmpty(comboBoxState)))
return;
else
{
this.Invoke((MethodInvoker)delegate { pictureBox1.Hide(); });
this.Invoke((MethodInvoker)delegate { labelNoImage.Show(); });
}
}

string url = "http://info.sigmatek.net/downloads/SalesMap/" + name;

try
{
this.Invoke((MethodInvoker)delegate { labelNoImage.Hide(); });
this.Invoke((MethodInvoker)delegate { pictureBox1.Show(); });
this.Invoke((MethodInvoker)delegate { pictureBox1.Load(url); });
}
catch
{
this.Invoke((MethodInvoker)delegate { pictureBox1.Hide(); });
this.Invoke((MethodInvoker)delegate { labelNoImage.Show(); });
}
}


and
this.Invoke((MethodInvoker)delegate { pictureBox1.Load(url); });
is throwing an Argument Exception (
Parameter is not valid
) that the catch block is not catching. Why would a try{}catch{} not catch an exception?

Answer

Why would a try{}catch{} not catch an exception?

Because it's being thrown in another thread. That's what Invoke does: It executes the code in another thread. During the time that's happening, the current thread blocks. Given that the two threads are temporarily yoked together like that, it's not crazy to think the invoking thread would be able to catch the exception, but it doesn't catch it for me either. This is empirical; I may get a comment saying I'm dead wrong about the "why" here.

Here's how I'd rewrite that:

this.Invoke((MethodInvoker)delegate {
    try
    {
        labelNoImage.Hide();
        pictureBox1.Show();
        pictureBox1.Load(url);
    }
    catch (Exception ex)
    {
        pictureBox1.Hide();
        labelNoImage.Show();
    }
});

It's more readable, too.

Comments