Я бы порекомендовал MSMQ. :) Я не уверен, почему вы не используете его, однако вы упомянули об этом в своем вопросе. Это в значительной степени именно то, что MSMQ был разработан для ... длительных событий между приложениями. Он в первую очередь поддерживает модель сообщений pub / sub ... которая на основе вашего "идеального решения" - именно то, что вам нужно: TC - издатель, TP - подписчик. TC регистрирует задачу, а затем отбрасывает сообщение в своей очереди публикации. Задача TP не должна быть запущена и запущена для TC, чтобы успешно отбрасывать сообщение в своей очереди, однако, когда задача TP работает, она будет получать уведомления и обрабатывать сообщения в очереди в порядке приоритета поступления.
Если MSMQ не вариант, вы также можете использовать WCF. Вместо pub / sub, с WCF вы можете выбрать модель сообщения FAF (запустить и забыть). TP будет публиковать сервис, который будет использовать TC. TC нужно будет только отправить сообщение службе TP, чтобы уведомить TP о новых задачах. Недостатком этой модели является то, что TC зависит от TP, что может быть меньше, чем идея. TP также должен быть запущен для успешного функционирования TC, поскольку он зависит от сервиса TP. При использовании подхода MSMQ ни TP, ни TC не зависят друг от друга, они зависят только от MSMQ (подход с более низкой связью).
РЕДАКТИРОВАТЬ:
Пример использования MSMQ для запуска событий из TC и ответа на события в TP.
// TC message queue manager, sends messages
public class TaskMessageQueueManager
{
public void NotifySubscribersOfNewTasks()
{
var queue = getQueue(".\private$\TaskNotifications");
queue.Send("Tasks waiting.");
}
private MessageQueue getQueue(string name)
{
MessageQueue queue = null;
try
{
if (!MessageQueue.Exists(name))
{
queue = MessageQueue.Create(name);
}
else
{
queue = new MessageQueue(name);
}
}
catch (Exception ex)
{
throw new InvalidOperationException("An error occurred while retrieving the message queue '" + name + "'.", ex);
}
return queue;
}
}
// TP message queue handler, receives messages
public class TaskMessageQueueHandler
{
private Thread m_thread;
private ManualResetEvent m_signal;
public void Start()
{
m_signal = new ManualResetEvent(false);
m_thread = new Thread(MSMQReceiveLoop);
m_thread.Start();
}
public void Stop()
{
m_signal.Set();
}
private void MSMQReceiveLoop()
{
bool running = true;
MessageQueue queue = getQueue(".\private$\TaskNotifications");
while (running)
{
try
{
var message = queue.Receive(); // Blocks here until a message is received by MSMQ
if (message.Body.ToString() == "Tasks waiting.")
{
// TODO: Fire off process, perhaps another thread, to handle waiting tasks
}
if (m_signal.WaitOne(10)) // Non-blocking check for exit signal
{
running = false; // If Stop method has been called, the signal will be set and we can end loop
}
}
catch
{
// handle error
running = false;
}
}
}
}
Сообщение не должно быть простым текстом. Вы можете отправить объект или граф объекта, и он автоматически будет сериализован и отформатирован как XML по умолчанию. Я считаю, что вы также можете сериализовать данные в двоичном формате, если это то, что вам нужно. В любом случае, вы заметите, что нигде нет вызовов или опросов Thread.Sleep. Цикл завершается на основе ManualResetEvent, позволяя вам аккуратно завершить поток без принудительной отмены.