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

Должен ли каждый BeginInvoke следовать EndInvoke?

Эта страница в документации MS, охватывающая асинхронность в приложениях Windows Forms, гласит:

Вы можете вызвать EndInvoke для получения возвращаемого значения из делегата, если это необходимо, но это не требуется. (выделено мной)

Эта страница, охватывающая общий случай асинхронных делегатов, описывает что-то другое:

Независимо от того, какой метод вы используете, всегда вызывайте EndInvoke для завершения асинхронного вызова.

Эти два, кажется, находятся в прямом конфликте.

Что верно? Может кто-нибудь объяснить?

см. также сообщение Фила Хаака.

Связано: Опция EndInvoke необязательна, необязательно, необязательно?

4b9b3361

Ответ 1

Если в документации для интерфейса явно не указано иначе, вы должны вызвать EndInvoke для каждого места, которое вы вызываете BeginInvoke. Основная причина заключается в том, что EndInvoke является единственным временем, когда владелец может безопасно освобождать определенные ресурсы, которые могут быть выделены для вызова BeginInvoke (например, WaitHandle).

Но есть исключения из этого правила. API, такие как Control.BeginInvoke, не требуют EndInvoke, но они явны в документации.

Ответ 2

Оба истины - это разные вызовы.

В общем случае вы всегда должны вызывать EndInvoke, чтобы освободить все ресурсы, полученные асинхронным вызовом.

Однако команда Windows Forms гарантирует, что вам не нужно делать это для Control.Invoke. Возможно, вам нужно сделать это для других реализаций ISynchronizeInvoke.

Ответ 3

Я использовал метод fire-and-forget с делегатами до того, где результаты были "полезны, если они доступны, но не требуются". Просто помните, что у вас нет гарантий завершения с помощью этого метода. В частности, здесь одно место, которое я использую:

  • Запустите делегат для проверки обновлений приложений.
  • Делегат начинает веб-запрос с тайм-аутом
  • Если возникает ошибка/время ожидания или если приложение обновлено, метод просто возвращает
  • Если приложение устарело, я помещаю сообщение systray без фокуса, указывающее так (без значка systray, если обновление не доступно).

В любом случае приложение продолжает работать без прерывания.