Вопрос по c#, multithreading – Маршалл к нитке вручную

6

В WinForms у вас естьControl.BeginInvoke()Это означает, что вы можете перенаправить вызов из фонового потока в основной поток пользовательского интерфейса, который создал дескриптор элемента управления.

Это хорошо, но как (в C #) вы сделаете это между двумя "стандартными" quot; потоки?

Я написал служебную шину, в которой есть процессорный поток для приема сообщений. Я хочу, чтобы таймер сработал, что заставляет поток процессора что-то делать, а не код, запущенный в потоке таймера.

Конечно, я могу использовать синхронизацию потоков (Monitor/using() {...}) но задавался вопросом, как это было сделано нормально.

Ваш Ответ

2   ответа
1

Windows Forms запускаетцикл сообщенийВот почему вы можете маршалировать в поток пользовательского интерфейса для всех видов задач - он многократно ищет сообщения в своей очереди, которые могут быть отправлены через границы потока.

Если вы хотите сделать это вручную, либо создайте свой собственный цикл сообщений (для одного или нескольких потоков), либо намного проще, используйте примитивы синхронизации.AutoResetEvent Казалось бы, подходящим для этой ситуации. Вам просто нужно позвонитьSet а такжеWaitOne методы в правильных точках, действительно (и быть в курсе тупиков, конечно).

11

К сожалению, здесь трудно дать ответ, поскольку он сильно зависит от характера потока.

Маршалинг между нитями не является магией. Существует основной механизм, который позволяет это сделать. Например, в WinForms функции стиля Control.Invoke работают через передачу сообщений. В ветке пользовательского интерфейса имеется сообщение, которое в конечном итоге обработает это сообщение и преобразует его в вызов маршала.

Чтобы маршалировать вызов между стандартным потоком, он должен иметь некоторую возможность, с помощью которой он может обнаружить, что маршальный вызов хочет произойти, а затем сделать этот вызов возможным. Обычно это делается путем передачи сообщений какого-либо рода.

ИМХО, самый стандартный способ сделать это - заставить ваш поток реализовать, предоставить и установить SynchronizationContext. Это более стандартный способ определения механизма маршалинга между потоками.

SynchronizationContext был ответом, который я искал - спасибо! Neil Barnwell

Похожие вопросы