Иногда использую (в нагрузке)
this.BeginInvoke((MethodInvoker) delegate {
// some code
});
или
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(замените "this" на свою переменную формы, если вы обрабатываете событие в экземпляре, отличном от "this").
Это помещает вызов в цикл окон-форм, поэтому он обрабатывается, когда форма обрабатывает очередь сообщений.
[обновлено по запросу]
Методы Control.Invoke / Control.BeginInvoke предназначены для использования с потоками и являются механизмом для передачи работы в поток пользовательского интерфейса. Обычно это используется рабочими потоками и т. Д. Control.Invoke выполняет синхронный вызов, тогда как Control.BeginInvoke выполняет асинхронный вызов.
Обычно они используются как:
SomeCodeOrEventHandlerOnAWorkerThread()
{
// this code running on a worker thread...
string newText = ExpensiveMethod(); // perhaps a DB/web call
// now ask the UI thread to update itself
this.Invoke((MethodInvoker) delegate {
// this code runs on the UI thread!
this.Text = newText;
});
}
Он делает это, помещая сообщение в очередь сообщений Windows; поток пользовательского интерфейса (в какой-то момент) удаляет сообщение из очереди, обрабатывает делегата и сигнализирует рабочему о завершении ... пока все хорошо ;-p
ХОРОШО; Итак, что произойдет, если мы используем Control.Invoke / Control.BeginInvoke в потоке пользовательского интерфейса? Он справляется ... если вы вызываете Control.Invoke, достаточно разумно знать, что блокировка очереди сообщений вызовет немедленную взаимоблокировку - поэтому, если вы уже находитесь в потоке пользовательского интерфейса, он просто немедленно запускает код ... так что нам не помогает ...
Но Control.BeginInvoke работает иначе: он всегда помещает работу в очередь, даже если мы уже находимся в потоке пользовательского интерфейса. Это действительно простой способ сказать «через мгновение», но без неудобств, связанных с таймерами и т. Д. (Которые в любом случае должны будут сделать то же самое!).