Thread error: Control accessed from a thread that is not the one in which it was created

Asked

Viewed 951 times

0

I have a code pad and I need it to run every x seconds, so I used the class Timer and passed as parameter the method I want to execute, and the times, start and interval. However the code is popping an exception, accusing System.InvalidOperationException: 'Operação entre threads inválida: controle 'lblTotalEncontrados' acessado de um thread que não é aquele no qual foi criado.' that controle lblTotalFind is an attribute of my form, I would like to know how do for the class thread Timer can change and manipulate all attributes of my form.

Follows the main part of the code:

//Usando a classe Timer Passando a função e os tempos como parâmetro
System.Threading.Timer t = new System.Threading.Timer(TimerCallback, null, 0, 120000);

//Método invocado passado para a classe Timer
public void TimerCallback(Object o)
        {
            //Todas partes desse bloco de código manipula atributos do formulário que está em outra thread

            this.txtQuantidadeHistorico.Text = this.topHistoricoUser.ToString();
            this.txtQuantidadeHistorico.Refresh();
            ResetLabelTransferidos_Encontrados();            
            SetTotalFilesInDirectory(directoryInfoSource);
            Process(directoryInfoSource);
            UpdateTxtUltimos();
        }

1 answer

2

This happens because your event is running in a thread and its controls were created in the thread main. Unfortunately you cannot access them directly in your thread.

The most correct way to solve this problem is to keep the part of the code that does not interact with the components of the form in one method and all the rest in another.

Below is an example of how you can build a method to do this operation:

public delegate void TimerCallbackDelegate(object o);

//Método invocado passado para a classe Timer
public void TimerCallback(Object o)
{
    //Verifica se é necessário invocar esse método na thread principal para interagir com os controles
    if (InvokeRequired)
    {
        //Invoca este próprio método
        Invoke((TimerCallbackDelegate)TimerCallback, o);
    }
    else
    {
        //Aqui seu código estará rodando na thread principal e será possível interagir com os componentes
        txtQuantidadeHistorico.Text = "teste";
    }
}

Browser other questions tagged

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