views:

101

answers:

1

Suppose I have some code which is running in the UI thread, which spawns a new thread to do work in the background, and then goes on to do UI work. When the background work is done, BeginInvoke is called from the new thread. If the UI work is still going on, will the callback given to BeginInvoke interrupt the UI work, or will it wait?

Code example - add a button called button1 to a form and add button1_Click to its click event, and then add this to the form:

bool continueWork = true;

private void button1_Click(object sender, EventArgs e)
{
    Thread workThread = new Thread(performBackgroundWork);

    workThread.IsBackground = true;
    workThread.SetApartmentState(ApartmentState.STA);
    workThread.Start();

    for (long i = 0; i < long.MaxValue; i++)
    {
        if (!continueWork)
            break;

        button1.Text = i.ToString();
    }
}

private void performBackgroundWork()
{
    Thread.Sleep(1);
    button1.BeginInvoke(new MethodInvoker(stopUIWork));            
}

private void stopUIWork()
{
    continueWork = false;
}

What is button1's text after it is clicked?

+4  A: 

BeginInvoke adds the delegate to a queue (the message queue to be exact). So the answer is no, they won't get interrupted. Your button click handler is in fact executed due to a message in the message queue as well.

EDIT: Sorry, I forgot to answer your second question, but you can probably figure that out by yourself. The button text will be long.MaxValue - 1. You would probably want to execute stopUIWork without using BeginInvoke.

wj32