Это то, что, я думаю, может происходить в вашей кодовой базе.
Обычный сценарий: вы нажимаете на кнопку.Не используйте цикл Parallel.Foreach.Используйте класс Dispatcher и вставьте код для запуска в отдельном потоке в фоновом режиме.Как только фоновый поток завершит обработку, он вызовет основной поток пользовательского интерфейса для обновления пользовательского интерфейса.В этом сценарии фоновый поток (вызываемый через Dispatcher) знает о главном потоке пользовательского интерфейса, который требуется отозвать.Или просто сказал, что основной поток пользовательского интерфейса имеет свою собственную идентификацию.
Использование цикла Parallel.Foreach: Как только вы запускаете цикл Paralle.Foreach, платформа использует поток пула потоков.Потоки ThreadPool выбираются случайным образом, и исполняемый код никогда не должен делать никаких предположений относительно идентичности выбранного потока.В исходном коде очень возможно, что поток диспетчера, вызванный через цикл Parallel.Foreach, не может определить поток, с которым он связан.Когда вы используете явный поток, тогда он работает нормально, потому что явный поток имеет свою собственную идентичность, на которую может положиться исполняемый код.
В идеале, если ваша основная задача заключается в том, чтобы поддерживать отзывчивость пользовательского интерфейса, сначала вы должны использовать класс Dispatcher, чтобы поместить код в фоновый поток, а затем использовать любую логику, которую вы хотите ускорить в целом.