Зачем использовать Action в этом коде?
Привет
Я вижу следующий код:
void UpdateMessage (string message)
{
Action action = () => txtMessage.Text = message;
this.Invoke (action);
}
Зачем использовать 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);
}
}
Ответы
Ответ 1
Поскольку этот код работает с другим потоком от пользовательского интерфейса и должен быть привязан к потоку пользовательского интерфейса с помощью Invoke
.
В документации для Control.Invoke()
указано:
Выполняет указанный делегат в потоке, которому принадлежит дескриптор окна управления.
Это необходимо, потому что базовая инфраструктура Windows требует, чтобы операции над дескриптором окна выполнялись потоком, которому принадлежит дескриптор окна.
Ответ 2
Если UpdateMessage вызывается из другого потока, вам необходимо вызвать в основной поток, чтобы взаимодействовать с элементами GUI.
Если вы используете только txtMessage.Text = message
, вы получите CrossThreadOperationException
Ответ 3
Вы должны работать с контрольными свойствами в потоке пользовательского интерфейса, иначе вы получите исключение.
Control.Invoke() выполнит ваш делегат, отправив сообщение окна в цикл сообщений окна.
Но вы можете оптимизировать код, чтобы предотвратить ненужную синхронизацию потоков, когда это не требуется:
void UpdateMessage (string message)
{
if(InvokeRequired)
{
Invoke((Action)()=>UpdateMessage(message));
return;
}
txtMessage.Text = message;
}