C# で、通信に MSMQ を使用する 2 つの個別の Windows フォーム アプリケーションを作成しました。これがどのように機能するかですが、それは十分に単純に見えました:
- 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();
}
}
どこで私は間違えましたか?私はどこに行ったのですか?
どうもありがとう、Stephane.P
編集: MSMQ ハンドラーがイベント送信の前後のどこかで Stop() で停止されると、詳細ウィンドウが表示され、すぐに消えます...
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);