Это лямбда-оператор, и читается как «идет».В MSDN есть хорошее введение: Лямбда-выражения (Руководство по программированию в C #)
Одна из проблем, связанных с вашим примером, заключается в том, что вы запускаете новый поток для обновления пользовательского интерфейса, пользовательский интерфейс по своей сути единичный.Это связано с тем, что фоновые обновления обычно не подходят (если вы вручную / явно не проверяете InvokeRequired
и не вызываете Invoke()
при необходимости.
Что касается потоков в пользовательском интерфейсе ...
В WinForms каждый Form
или Control
создается в определенном потоке («потоке пользовательского интерфейса»), и вы можете думать о том, что этот поток является владельцем этого элемента управления (не совсем правильный, но хороший способосмыслить это). Обновление пользовательского интерфейса из этого потока является безопасным, обновление пользовательского интерфейса из другого потока создает риск коллизий и повреждения, а также всех обычных рисков параллельного / асинхронного программирования.
... Итак ...Как безопасно обновить пользовательский интерфейс из фонового потока, не блокируя пользовательский интерфейс? Короче говоря - вы не можете - лучшее, что вы можете сделать, это заблокировать его на минимум , необходимый длядата пользовательского интерфейса.Это где InvokeRequired
и Invoke()
входят ...
Вот пример: вы должны быть в состоянии вставить это в код новой формы с помощью кнопки и текстового поля.
Для использования:
Попробуйте закомментировать либо вызов SetTextAsyncSafe()
, либо SetTextAsyncSafe()
- выполняетсяоба могут сбить вас с толку, поскольку они не обязательно будут выполняться в том порядке, в котором они называются (они работают асинхронно, помните?).
Затем установите точку останова на SetText()
.Вы должны увидеть, что «безопасный» вызов на самом деле вызовет метод дважды - первый вызов обнаружит InvokeRequired
и во второй раз вызовет метод для правильного потока при Invoke()
обращении к нему.
Вы должны увидеть исключение, которое выдается, когда SetTextAsyncUnsafe()
фактически получает операторы textBox1.Text = value;
.Исключением будет InvalidOperationException
с сообщением «Операция в нескольких потоках недопустима» - вы можете использовать этот термин в Google для получения более подробной информации.
Код:
private void button1_Click(object sender, EventArgs e)
{
SetTextAsyncSafe("This update was made from the UI Thread by using Invoke()");
SetTextAsyncUnsafe("This update was made directly from the background thread and can cause problems");
}
private void SetTextAsyncUnsafe(string value)
{
new Thread(() => SetText(value, false)).Start();
}
private void SetTextAsyncSafe(string value)
{
new Thread(() => SetText(value, true)).Start();
}
private void SetText(string value, bool checkInvokeRequired)
{
if (checkInvokeRequired)
{
if (InvokeRequired)
{
Invoke(new Action(() => SetText(value, checkInvokeRequired)));
return; // early exit
}
}
textBox1.Text = value;
}