Шаблон, который вам может пригодиться, - это проверить в верхней части функции, которые взаимодействуют с графическим интерфейсом, чтобы увидеть, работаете ли вы в правильном потоке или нет, и заставить функцию вызываться самостоятельно, если это необходимо. Как это:
public delegate void InvocationDelegate();
public void DoGuiStuff(){
if (someControl.InvokeRequired){
someControl.Invoke(InvocationDelegate(DoGuiStuff));
return;
}
//GUI manipulation here
}
Использование этого паттерна - если при вызове метода вы находитесь в правильном потоке, он не вызывает сам себя, но если вы находитесь в другом потоке, он будет вызывать сам себя, а затем возвращаться (поэтому логика манипуляции GUI только когда-либо называется один раз в любом случае).