Method is executed by clicking the button despite doing "button01.Enabled = false"

Asked

Viewed 80 times

1

I want to disable a button while the method does not finish. I used button01.Enabled = false;, but even clicking while the button is disabled, the method is called again after it ends.

For example, when I run the method below and I click three times on the button during the three seconds it is disabled it appears "TEST" four times on output.

private void buttonSendUsers_Click(object sender, EventArgs e)
{
    Console.WriteLine("TEST");        

    buttonSendUsers.Enabled = false;

    Thread.Sleep(3000); //teste

    buttonSendUsers.Enabled = true;

    return;
}

How can I make the button not execute the method while disabled?

2 answers

1


I found a question like this in the O.R., and I liked it of that answer:

button1.Enabled = false;
Task.Factory.StartNew(() => {
    // execução lenta aqui, se não for lenta, não faz sentido
}).ContinueWith(task => {
    button1.Enabled = true;
}, TaskScheduler.FromCurrentSynchronizationContext());

I put in the Github for future reference.

There’s another.

0

The answer code is right, but it’s hard to understand.

Simpler:

private void buttonSendUsers_Click(object sender, EventArgs e)
{
    buttonSendUsers.Enabled = false;
    Task.Run(() => {
        // Sua tarefa aqui
        Thread.Sleep(3000);
        buttonSendUsers.Enabled = true;
    });
}

If you use the above code, you will have an error in debugging time, but at runtime it works normally.

Error:

System.Invalidoperationexception: 'Invalid thread operation: buttonSendUsers control accessed from a thread that is not the one in which it was created.'

The error is due to calling interface objects in a Thread that is not that of the interface, there are two ways not to occur error:

Disabling extra conference at debug time

Call the next code in the form (not recommended to do this as you may have sync issues):

CheckForIllegalCrossThreadCalls = false;

It simply disables this conference at debug time.

Invoking Method in Interface Thread

calling:

Invoke((Action)(() => { buttonSendUsers.Enabled = true; }));

Or:

BeginInvoke((Action)(() => { buttonSendUsers.Enabled = true; }));

To rehabilitate the button, the second form does so asynchronously.

Code "thread safe":

private void buttonSendUsers_Click(object sender, EventArgs e)
{
    buttonSendUsers.Enabled = false;
    Task.Run(() => {
        // Sua tarefa aqui
        Thread.Sleep(3000);
        BeginInvoke((Action)(() => { buttonSendUsers.Enabled = true; }));
    });
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.