Критические разделы используются для сериализации доступа к коду. Для обновления графического интерфейса пользователя вы должны принять к сведению, что только основной поток должен обновлять элементы графического интерфейса.
Так что, если вашему потоку необходимо обновить элемент GUI, он должен делегировать это основному потоку. Для этого вы можете использовать разные техники:
Самый простой - использовать метод Synchronize в вашем коде потока. Когда вызывается Synchronize, ваш поток приостанавливается, код, предоставленный вами для Synchronize, будет выполняться в контексте основного потока, а затем ваш поток возобновляется.
Если вам не нравится, когда ваш поток останавливается каждый раз, когда вызывается этот фрагмент кода, вы можете использовать метод Queue. Очередь отправляет ваш запрос в очередь сообщений целевого потока (здесь основной поток), поэтому ваш поток не остановится, но пользовательский интерфейс может обновиться не сразу, в зависимости от того, насколько занята очередь сообщений основного потока.
Другим способом достижения этой цели является отправка пользовательских сообщений Windows в основной поток с помощью функций API SendMessage или PostMessage. В этом случае вы должны определить пользовательское сообщение и отправить его в основной поток всякий раз, когда вам нужно изменить элемент пользовательского интерфейса. Ваш основной поток должен предоставить обработчик сообщений для этого типа сообщений и обрабатывать полученные сообщения. Следствием этого является нечто похожее на использование метода Queue.