我在 C# 中创建了两个单独的 Windows 窗体应用程序,它们使用 MSMQ 进行通信。这是它的工作原理,虽然它看起来很简单:
- App1 向 App2 发送详细信息请求。
- App2 创建一个事件来打开窗口。
- App2 打开一个“详细信息”窗口。
我唯一的问题是,当收到消息时,“详细信息”窗口出现后冻结。
当我在一个使用线程的对象中处理 MSMQ 消息处理时,我怀疑问题来自那里......但我没有处理 MSMQ 消息或应用程序部分之间的特定事件处理的经验。
这是我用于 App2 的部分代码:
/*Class declared in the Core namespace*/
public class TaskMessageQueueHandler
{
public TaskMessageQueueHandler()
{
this.Start();
}
private Thread m_thread;
private ManualResetEvent m_signal;
public event System.EventHandler messageReceived;
public void Start()
{
m_signal = new ManualResetEvent(false);
m_thread = new Thread(MSMQReceiveLoop);
m_thread.Start();
}
public void Stop()
{
m_signal.Set();
}
protected virtual void SendEvent(object sender, EventArgs e)
{
if (messageReceived != null)
messageReceived(this.message, e);
}
public string message;
private void MSMQReceiveLoop()
{
bool running = true;
MessageQueue queue = new MessageQueue(@".\Private$\queue1");
while (running)
{
try
{
var message = queue.Receive();
message.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" });
this.message = message.Body.ToString();
string m = this.message;
SendEvent(m, System.EventArgs.Empty);
if (m_signal.WaitOne(10))
{
running = false;
}
}
catch
{
Console.WriteLine("ERROR");
running = false;
}
}
}
}
/*Main process, in the Program namespace*/
[...]
Core.TaskMessageQueueHandler tmqh = new Core.TaskMessageQueueHandler();
EventListener el = new EventListener();
tmqh.messageReceived += new System.EventHandler(el.ShowDetails);
[...]
/* Class in the Program namespace */
class EventListener
{
public void ShowDetails(object sender, EventArgs e)
{
int numero = int.Parse(sender as string);
Details details = new Details(numero);
details.Show();
}
}
我哪里做错了?我去哪里对了?
非常感谢,斯蒂芬.P
编辑:如果在事件发送周围的任何地方使用 Stop() 停止 MSMQ 处理程序,则会出现详细信息窗口然后立即消失......
EDIT2:在Slugart给出的解决方法之后,我设法完成了这项工作:
class EventListener
{
Main control;
public EventListener(Main main)
{
control = main;
}
public void ShowDetails(object sender, EventArgs e)
{
int numero = int.Parse(sender as string);
control.Invoke((Action)(() => ShowDetails(numero)));
}
private void ShowDetails(int numero)
{
Details details = new Details(numero);
details.Show();
}
}
使用如下:
Core.TaskMessageQueueHandler tmqh = new Core.TaskMessageQueueHandler();
EventListener el = new EventListener(this);
tmqh.messageReceived += new System.EventHandler(el.ShowDetails);