Вы имеете в виду Delegate.Invoke / BeginInvoke или Control.Invoke / BeginInvoke?
- Delegate.Invoke: выполняется синхронно в том же потоке.
- Delegate.BeginInvoke: выполняется асинхронно в потоке потоков.
- Control.Invoke: выполняется в потоке пользовательского интерфейса, но вызывающий поток ожидает завершения, прежде чем продолжить.
- Control.BeginInvoke: выполняется в потоке пользовательского интерфейса, а вызывающий поток не ожидает завершения.
В ответе Тима упоминается, когда вы, возможно, захотите использовать BeginInvoke, хотя я подозреваю, что он в основном предназначен для Delegate.BeginInvoke.
Для приложений Windows Forms я бы посоветовал вам обычно использовать BeginInvoke. Таким образом, вам не нужно беспокоиться о взаимоблокировке, например, - но вы должны понимать, что пользовательский интерфейс, возможно, не был обновлен, когда вы в следующий раз посмотрите на него! В частности, вы не должны изменять данные, которые поток пользовательского интерфейса может использовать для отображения. Например, если у вас есть свойства Person с именами FirstName и LastName, и вы указали:
person.FirstName = "Kevin"; // person is a shared reference
person.LastName = "Spacey";
control.BeginInvoke(UpdateName);
person.FirstName = "Keyser";
person.LastName = "Soze";
тогда пользовательский интерфейс может в конечном итоге отобразить «Keyser Spacey». (Существует внешняя вероятность, что он может отобразить «Кевин Созе», но только через странность модели памяти.)
Однако, если у вас нет такого рода проблем, Control.BeginInvoke будет проще понять, и ваш фоновый поток не будет ждать без веской причины. Обратите внимание, что команда Windows Forms гарантировала, что вы можете использовать Control.BeginInvoke в режиме «запускай и забывай», то есть никогда не вызывая EndInvoke. Это не относится к асинхронным вызовам в целом: обычно каждый BeginXXX должен иметь соответствующий вызов EndXXX, обычно в обратном вызове.