1

Bumped into this code example today:

private void Form1_Load(object sender, EventArgs e)
{
    try
    {
        ThreadPool.QueueUserWorkItem(ShowMessage, null);
    }
    catch
    {

    }
}

private void ShowMessage(object obj)
{
    try
    {
        label1.Text = "Test"; // does't work and just goes into catch block
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }

    try
    {
        button1.Text = "Test"; // will actually set Text property of a button and only then throw an exception, which will be caught in corresponding catch block
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

I know one should use Invoke to work with control's properties. What puzzles me is why it actually changes text field anyways despite the exception and doesn't sets label's field. I'd like to know what's happening inside it.

Here's an answer that partially explains why is it happening, so as I got it SetWindowText doesn't work for labels from different thread, but it does work for buttons. Am I right?

Also, I would like to know if this behaviour is persistent. Does it depends on something? Attached debugger? OS or .NET version maybe? 64 vs 32 bits?

Thanks in advance!

Community
  • 1
  • 1
SimpleV
  • 396
  • 4
  • 14

1 Answers1

4

This is a behavior I explained here: https://stackoverflow.com/a/37898886/869621

Long story short, there is an internal text cache activated for some controls. When active, this cache is set before executing the line that throws the cross-thread exception. Therefore, the next time the UI is refreshed, the control text has the expected value even though an exception was thrown.

For some reasons, this cache isn't enabled for labels. That's why you're able to set the text of the button but not of the label.

As to know whether this behavior is persistent, yes and no. Yes it will consistently work on the current version of .NET. But no, it's an implementation detail and is not documented so it could break when the .NET framework is updated. Don't rely on it, and use only the UI thread to update your controls.

Community
  • 1
  • 1
Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94