Вы можете использовать функции Invoke и BeginInvoke, чтобы получить код для выполнения в потоке GUI.Вы можете заставить другой поток вызывать событие, а затем обрабатывать его в главной форме, а затем ваша основная форма может вызывать этот обратный вызов в свой собственный поток (используя InvokeRequired, а затем Invoke) для запуска новой формы.
Если вы работаете в фоновом режиме, вы можете использовать метод OnProgressChanged, чтобы использовать его в качестве сигнала для вашего приложения.
Кроме того, взгляните на эту превосходную книгу