В первом сценарии, поскольку поток B знает , что это не поток пользовательского интерфейса, он может просто вызвать .Invoke(...)
.
При наличии двух потоков, не относящихся к пользовательскому интерфейсу, вам придется использовать какую-то передачу / очередь сообщений. Вы не можете просто прервать поток A, чтобы запустить работу; Вы должны закодировать поток A, чтобы (например) проверить очередь на работу, снять элемент с очереди и выполнить его. Что в значительной степени и делает winforms, благодаря циклу сообщений Windows. Неважно, если это не ответ, который вы ищете - это то, что он есть.