Подтвердить что ты не робот

Как использовать BeginInvoke С#

Не могли бы вы объяснить это мне, пожалуйста:

someformobj.BeginInvoke((Action)(() =>
{
    someformobj.listBox1.SelectedIndex = 0;
}));

Не могли бы вы рассказать мне, как я могу использовать begininvoke точно? Что такое тип Action? Почему есть пустые скобки ()? И что это значит =>?

4b9b3361

Ответ 1

Action - это тип делегата, предоставляемый платформой .NET. Action указывает на метод без параметров и не возвращает значение.

() => - синтаксис лямбда-выражения. Лямбда-выражения не относятся к типу Delegate. Invoke требует Delegate, поэтому Action можно использовать для обертки лямбда-выражения и обеспечения ожидаемого Type до Invoke()

Invoke вызывает упомянутый Action для выполнения в потоке, который создал дескриптор окна управления. Часто требуется изменение потоков, чтобы избежать Exceptions. Например, если вы пытаетесь установить свойство Rtf на RichTextBox, когда требуется Invoke, без первого вызова Invoke, будет выбрано исключение Cross-thread operation not valid. Перед вызовом Invoke откройте Control.InvokeRequired.

BeginInvoke - это асинхронная версия Invoke. Асинхронный означает, что поток не будет блокировать вызывающего абонента в отличие от синхронного вызова, который блокируется.

Ответ 2

Я думаю, ваш код относится к Windows Forms.
Вы вызываете BeginInvoke, если вам нужно что-то выполнить асинхронно в потоке пользовательского интерфейса: изменить свойства управления в большинстве случаев.
Грубо говоря, это достигается передачей делегата какой-либо процедуре, которая периодически выполняется. (обработка цикла сообщений и все такое)

Если BeginInvoke вызывается для типа Delegate, делегат просто вызывается асинхронно.
(Invoke для версии синхронизации.)

Если вам нужен более универсальный код, который отлично работает для WPF и WinForms, вы можете рассмотреть параллельную библиотеку задач и запустить Task с помощью context. (TaskScheduler.FromCurrentSynchronizationContext())

И добавить немного к уже сказанным другими: Lambdas можно рассматривать как анонимные методы или expressions.
И поэтому вы не можете просто использовать var с lambdas: компилятор нуждается в подсказке.

UPDATE:

для этого требуется .Net v4.0 и выше

// This line must be called in UI thread to get correct scheduler
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();

// this can be called anywhere
var task = new System.Threading.Tasks.Task( () => someformobj.listBox1.SelectedIndex = 0);

// also can be called anywhere. Task  will be scheduled for execution.
// And *IF I'm not mistaken* can be (or even will be executed synchronously)
// if this call is made from GUI thread. (to be checked) 
task.Start(scheduler);

Если вы запустили задачу из другого потока и должны дождаться своего завершения, task.Wait() будет блокировать вызов потока до конца задачи.

Подробнее о задачах здесь.