У меня в рабочем потоке выполняются вычисления, а в другом (основном) отображается GUI и прогресс выполнения этих вычислений.
Организовать обмен можно двумя способами:
1) В рабочем потоке вызывать BeginInvoke и передавать через него информацию о проделанной работе
2) В рабочем потоке обновлять переменную с информацией о проделанной работе, а в основном потоке периодически опрашивать эту переменную и обновлять индикацию. Естественно, переменную нужно защитить критической секцией.
Оба эти метода работают плохо если рабочий поток обновляет информацию очень часто.
В первом случае очередь основного потока забивается бесчисленными сообщениями BeginInvoke, и GUI становится полумёртвым, так как остальные сообщения теряются в этой массе.
Во втором случае ситуация немного получше, но GUI так же подвисает, так как натыкается на (часто) залоченный объект. Естественно, если период обновления составляет около секунды, то это терпимо.
Я пришёл к выводу, что наилучшим способом является третий:
3) Позволить рабочему потоку обновлять информацию сколь угодно часто, но лишь изредка (например, 1 раз в секунду) пропускать эти изменения в GUI. В этом случае задерживать выполнение рабочего потока (Invoke вместо BeginInvoke), а выполнение основного потока никогда не тормозить.
Для решения этой задачи подошёл бы класс "временнОго фильтра", который и осуществлял бы эту задачу. То есть, проглатывал бы вызовы функции если они следуют очень часто и исполнял бы только те, которые случились не ранее заданного времени после предыдущего.