Очень очевидный вариант использования Invoke () - это когда вам нужно вызвать метод, возвращаемое значение которого вам нужно. Только Invoke () может обеспечить это для вас, он возвращает Object, метод возвращает значение.
В более слабом случае рабочий поток выдает результаты со скоростью, намного превышающей скорость пользовательского интерфейса. Использование Invoke () приведет к удушению рабочего, и список вызовов не может расти без ограничений. Это, однако, всего лишь бинты для решения более серьезной проблемы, не имеет смысла обновлять пользовательский интерфейс быстрее, чем может воспринимать человек. Один раз каждые 40 миллисекунд выглядит гладко для человеческого глаза. Вы по-прежнему хотите использовать Invoke (), если потоку пользовательского интерфейса требуется слишком много времени для обработки коллекции результатов. Классическими признаками возникновения проблемы, подобной этой, является зависание потока пользовательского интерфейса, отсутствие возможности рисовать и реагировать на события мыши и клавиатуры, потому что оно полностью перегружено запросами вызова. И поток пользовательского интерфейса оставался без ответа некоторое время после того, как рабочий завершил работу, занят работой над отставанием.
Другой случай - требования к блокировке объектов, которые вы передаете BeginInvoke (). Блокировка не требуется, если вы используете Invoke (), поток пользовательского интерфейса и рабочий поток не могут получить доступ к объекту одновременно. Это не относится к BeginInvoke, он продолжает работать, и если поток продолжает использовать один и тот же объект, вы должны защитить объект с помощью блокировки как в потоке пользовательского интерфейса, так и в рабочем. Если эта блокировка мешает работнику делать какие-либо успехи, вы можете также использовать Invoke (). Все это довольно редко, так как основной поток начинает выполнять делегат очень долго. И всегда полезно создать новый экземпляр объекта после того, как вы его вызвали, чтобы не было необходимости в блокировке.