понедельник, 3 января 2022 г.

Invoke




Суть метода Invoke довольно проста - он принимает делегат и выполняет его в том потоке, в котором был создан элемент управления, у которого вызывается Invoke.

Как вы могли заметить, если обращаться к контролам в WinForms не из того потока, в котором они были созданы, будет выброшено исключение.

Соответственно, метод Invoke полезен в случаях, когда необходимо работать с контролом из других потоков. 

Метод BeginInvoke делает то же самое, но асинхронно.

Небольшой пример использования Invoke:

private void ButtonInvoke_Click(object sender, EventArgs e)
{
    var myThread = new Thread(ThreadFunction);
    myThread.Start(); //метод выполняется в другом потоке
}

private void ThreadFunction()
{
    Thread.Sleep(1000);
    Action action = () => listBox1.Items.Add("value");
    // Свойство InvokeRequired указывает, нeжно ли обращаться к контролу с помощью Invoke
    if (InvokeRequired)
        Invoke(action);
    else
        action();
}


Стоит также отметить, что async/await, добавленные в C# 5, позволяют обойтись без Invoke:

private async void ButtonAsync_Click(object sender, EventArgs e)
{
    listBox1.Items.Add("first");
    await Task.Run(async () =>
    {
        await Task.Delay(1000);
    });
    // этот код будет продолжен в UI потоке, 
    // и здесь нет необходимости использовать Invoke
    listBox1.Items.Add("second");
}


Т.е. грубо говоря, если мне нужно изменить datagridview в другом потоке, я в своём первоначальном коде изменяю контрол с помощью Invoke и делегата. Action action = () => dataGridView1.DataSource = dsOpenPos.Tables[0]; if (InvokeRequired) Invoke(action); else action();


В оконных приложениях Windows существует так называемый поток пользовательского интерфейса (UI thread), по сути — основной поток приложения, создаваемый самым первым.

Он выполняет обработку оконных сообщений (Windows messages), вызывая в цикле функции GetMessage или PeekMessage. Если вы хотите что-то сделать с пользовательским интерфейсом, например, изменить строку в поле ввода, вы посылаете ему оконное сообщение.




Комментариев нет:

Отправить комментарий

Паттерн 'Репозиторий' в ASP.NET

  Последнее обновление: 1.11.2015         Одним из наиболее часто используемых паттернов при работе с данными является паттерн 'Репозито...