Стоимость InvokeRequired зависит от того, какой класс реализует ISynchronizeInvoke, и от конкретного случая использования. «Стоимость» будет сильно зависеть от используемой вами реализации. Однако, как правило, это довольно низкие накладные расходы. (Во многих случаях это может быть так же просто, как проверить, совпадает ли текущий поток с исходным потоком.)
Это, как говорится, если вам это нужно, это стоит затрат, ВСЕГДА. Даже если это только 1% времени, которое потребуется, оно должно быть включено. В противном случае вы запрашиваете сбой, блокировку или другое нежелательное поведение. В большинстве случаев, когда вы могли бы использовать это, вы должны всегда включать эту стоимость.
Наиболее распространенный вариант использования - синхронизация делегатов в потоке пользовательского интерфейса. В этом случае вы должны его использовать, иначе произойдут очень плохие вещи. Кроме того, в этом случае стоимость очень низкая по сравнению с ожиданием в потоке сообщений для взаимодействия с пользовательским интерфейсом, поэтому об этом действительно не стоит беспокоиться. *
Если вы используете его с пользовательской реализацией ISynchronizeInvoke, и это происходит в тесном цикле, и вы профилировали и обнаружили, что это вызывает проблемы для вас, тогда об этом стоит подумать. В этом случае, однако, я бы порекомендовал попытаться переработать сам алгоритм, чтобы избежать необходимости в максимально возможной синхронизации, но по-прежнему использовать InvokeRequired при необходимости.