2012-02-05 5 views
2

Есть ли способ в C# отправить сообщение другому потоку, основанному на имени потока или имени потока?Может ли одна тема общаться с другим?

В основном для проекта в школе, мой профессор хочет, чтобы мы делали сделку производителя/потребителя, но передавали объекты, сериализованные в строку (например, xml) от производителя к потребителю. Как только строка вытягивается из буфера в потребительском потоке, каждая из этих строк декодируется (включая поток) и обрабатывается, а исходный производитель уведомляется посредством обратного вызова. Итак, как мне отправить событие в исходный поток производителя только с идентификатором потока?

+0

Посмотрите - http://ru.wikipedia.org/wiki/Producer-consumer_problem – adatapost

ответ

1

Вы можете написать класс, который содержит словарь < string, thread> member, содержащий все ваши темы. Когда вы создаете поток, добавьте его в словарь, чтобы вы могли вернуть его по имени (ключу) позже из любого места в классе. Таким образом, вы также можете обмениваться ресурсами между вашими потоками, но обязательно блокируйте любые общие ресурсы, чтобы предотвратить проблемы с параллелизмом.

1

При использовании потоков вы не пытаетесь отправлять сообщения между ними. Темы могут использовать общую память для синхронизации - это называется синхронизированными объектами. Чтобы управлять потоками для системы потребителя/производителя, вы можете использовать очередь (структуру данных), а не систему сообщений. (см. пример здесь: C# producer/consumer).

Еще одно возможное решение (которое я бы не рекомендовал): вы можете использовать GetThreadId для возврата идентификатора данного родного потока. Тогда все, что вам нужно найти, это дескриптор потока и передать его этой функции. GetCurrentThreadId возвращает идентификатор текущего потока. Там вы можете получить доступ к свойству имени.

+0

Я с вами там. Просто наш профессор хочет, чтобы это было сделано так, потому что в конечном итоге часть этого будет перенесена на веб-службу на сервере (то есть на потребительском конце). Он просто настраивает нас для легкой интеграции с этим. Все еще не отвечает на мой вопрос, как вы называете метод в потоке, учитывая его номер или номер потока? Id скорее придерживайтесь .net apis, а не отправляйтесь на выигрыш. –

0

Сообщение просто вызов метода, и для вызова метода вам сначала нужен объект-экземпляр, который выставляет некоторые методы для вызова, поэтому отправка сообщения в поток означает поиск активного объекта, который живет в этом потоке и вызывает это особый метод.

Поиск объекта основного работника каждого потока может осуществляться через координатор ниток, так что если объект в определенном потоке хочет отправить сообщение к другому объекту (в другом потоке), это будет первым отправить это запрос координатору потоков, а координатор отправляет сообщение/запрос в пункт назначения.

1

Представьте, что вы управляете компанией, и вы могли бы нанять столько сотрудников, сколько вам было нужно, но каждый сотрудник был действительно целеустремлен, поэтому вы можете дать только один заказ . Вы не могли с ними справиться, верно? Поэтому, если бы вы были умным менеджером, то, что вы сделали бы, это сказать: «Ваш заказ», подождите от вашего почтового ящика, пока вы не получите письмо, в котором говорится, что делать, выполнять работу, а затем повторять ». Затем вы могли бы поместить рабочие элементы в папки входящих работников, поскольку вам нужна была проделанная работа.

Проблема в том, что произойдет, если вы дадите сотруднику долгосрочную задачу с низким приоритетом (скажем, «поехать в Топику, чтобы забрать арахисовое масло для пикника компании»). Сотрудник с радостью уйдет и сделает это. Но тогда здание загорается, и вам нужно знать, что если вы произведете заказ, «возьмите огнетушитель и выпустите огонь!» кто-то будет делать это быстро. Вы можете решить эту проблему, если у нескольких сотрудников есть один почтовый ящик. Таким образом, существует большая вероятность того, что кто-то будет готов выполнить заказ, чтобы окунуть пламя, и не уезжать через Канзас.

Угадайте, что? Темы - это трудные сотрудники.

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

Для двунаправленной связи вам понадобятся две очереди (одна для сообщения и одна для ответа). Причина в том, что ваш «основной» поток также является плохим сотрудником - он может обрабатывать ответы по одному за раз, а пока он обрабатывает ответ от одного работника, другой рабочий может вернуться с другим ответом. Вы хотите создать протокол координации запроса/ответа, чтобы исходный запросчик знал, к какому запросу относится ответ. Обычно запросы имеют идентификатор, а ответы ссылаются на идентификатор запроса, чтобы исходный запросчик знал, к какому запросу требуется каждый ответ ,

Наконец, вам нужна правильная синхронизация потоков (блокировка) в очередях, если она не встроена в очередь производителей/потребителей, с которой вы работаете. Представьте, что вы отправляли сообщение в папку «Входящие» рабочего, и этот рабочий так стремился прочитать сообщение, что он схватил его из вашей руки и разорвал его пополам. То, что вам нужно, - это возможность предотвратить одновременное обращение к очереди по нескольким потокам.

Смежные вопросы