Зачем использовать Action в этом коде? - PullRequest
12 голосов
/ 10 мая 2011

Привет, я вижу следующий код:

void UpdateMessage (string message)
{
    Action action = () => txtMessage.Text = message;
    this.Invoke (action);
}

Зачем использовать действие, а затем вызывать действие здесь?Почему бы просто не использовать txtMessage.Text = message для замены кода в теле функции?


Обновление

Более полная версия кода, представленная в комментарии, воспроизводитсяниже с подсветкой синтаксиса, отступом и т. д.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
        InitializeComponent(); 
        new Thread(Work).Start(); 
    } 

    void Work() 
    { 
        Thread.Sleep(5000); 
        UpdateMessage("My Garden"); 
    } 

    void UpdateMessage(string message) { 
        Action action = () => textBox1.Text = message; 
        this.Invoke(action); 
    } 
} 

Ответы [ 3 ]

20 голосов
/ 10 мая 2011

Поскольку этот код выполняется в потоке, отличном от пользовательского интерфейса, и должен быть перенаправлен в поток пользовательского интерфейса с помощью Invoke.

Документация для Control.Invoke() гласит:

Выполняет указанный делегат в потоке, которому принадлежит основной дескриптор окна элемента управления.

Это все необходимо, поскольку базовая среда Windows требует, чтобы операции с дескриптором окна выполнялись потоком, который владеет дескриптором окна.

12 голосов
/ 10 мая 2011

Если UpdateMessage вызывается из другого потока, вам нужно вызвать основной поток для взаимодействия с элементами графического интерфейса

Если вы используете txtMessage.Text = message, вы получите CrossThreadOperationException

4 голосов
/ 10 мая 2011

Вы должны работать со свойствами элемента управления в потоке пользовательского интерфейса, в противном случае вы получите исключение.

Control.Invoke () выполнит ваш делегат, отправив сообщение Windows в цикл сообщений окна.

Но вы можете оптимизировать код, чтобы предотвратить ненужную синхронизацию потоков, когда это не требуется:

void UpdateMessage (string message)
{
    if(InvokeRequired)
    {
        Invoke((Action)()=>UpdateMessage(message));
        return;
    }

    txtMessage.Text = message;
}
...