我会推荐 MSMQ。:) 我不确定您为什么不使用它,但是您在问题中确实提到了它。这几乎正是 MSMQ 的设计目的……应用程序之间的持久事件。它主要支持发布/订阅消息模型...基于您的“理想解决方案”正是您所需要的:TC 是发布者,TP 是订阅者。TC 注册任务,然后在其发布队列中删除一条消息。TP 任务不需要启动并运行,TC 就可以成功地将消息放入其队列中,但是当 TP 任务正在运行时,它将接收通知并按照到达的优先顺序处理队列中的消息。
如果 MSMQ 不是一个选项,您也可以使用 WCF。除了发布/订阅,您可以使用 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 退出,允许您干净地结束线程而无需硬中止。