Многопоточная прокачка сообщений без второй формы
У меня есть приложение C#, которое использует компонент COM. Этот COM-компонент требует обработки сообщений (Application.Run()) для его обработки. Это означает, что он застрял в главном потоке. Но недавно я обнаружил, что можно запустить другой Application.Run в другом потоке, который получает свой собственный ApplicationContext.
Поэтому я хочу разместить COM-компонент в своем собственном потоке внутри собственного Application.Run(), но я не могу понять, как начать работу в новом потоке без создания формы пользовательского интерфейса.
WindowsFormsSynchronizationContext, который мне нужен для связи с потоком, не создается до Application.Run(). Но как только Application.Run () вызван, я не могу понять, как получить SynchronizationContext. Если бы я мог просто вызвать одно событие в этом потоке, я мог бы использовать его для начальной загрузки всего этого (создания COM-объекта и т. Д.), Но, похоже, нет места, где можно было бы подключиться к новому циклу событий без формы.,
Я перепробовал все виды запутанных вещей, таких как установка фильтра сообщений (в новом потоке сообщений не возникает), копирование контекста выполнения в другой поток и попытка получить оттуда SynchronizationContext (он отказывается копировать ExecutionContext объекта). уже запущен поток), извлекает Thread.CurrentContext перед запуском Application.Run () и затем вызывает DoCallbBack() (DoCallback заканчивается в исходном потоке) и т. д. Ничего из того, что я пробовал, не работает.
1 ответ
Bryce,
Возможно, вам удастся адаптировать этот фрагмент из выступления Андерса Хейлсберга "Будущее C#". Это небольшой класс, который добавляет обработчик сообщений в поток, чтобы он мог открывать окна с помощью цикла REPL, и к ним будет прикреплен обработчик сообщений.
Код выглядит так:
using System.Windows.Forms;
using System.Threading;
class UserInterfaceThread()
{
static Form window;
public UserInterfaceThread()
{
var thread = new Thread(() => {
window = new Form();
var handle = window.Handle;
Application.Run();
});
thread.Start();
}
public void Run(Action action)
{
window.Invoke(action);
}
}
Обсуждение этого кода происходит через 1 час 5 минут после выступления Андерса, если вы хотите его просмотреть.