Это действительно зависит от того, сколько вы делаете. Блокировки не проблема, если вы не глупы программировать логику обновления.
Обычно вы идете клиент / сервер внутри. У пользовательского интерфейса есть своя собственная модель, которую он «рендерит», у логики своя собственная невизуальная модель.
Вы можете работать с 2 очередями (для модели, для визуала), в которые вставляются обновления статуса (операции для логики, обновления пользовательского интерфейса для визуальной модели).
Затем WPF - по срокам или по триггеру - извлекает обновления из очереди и обновляет модель, внося визуальные изменения в процессе работы.
Работает довольно хорошо в зависимости от "игры", которую вы делаете. Моя «игра» - это приложение для финансовой торговли, работающее почти так же (хотя у меня есть X визуальных очередей, поскольку на нескольких экранах есть свой собственный поток пользовательского интерфейса).