簡體   English   中英

線程和Form.Show()

[英]Thread and Form.Show()

我似乎在使用線程方面遇到麻煩。

首先讓我解釋一下應用程序是如何構建的。

我有一個擴展ApplicationContext的類,該類是整個應用程序的核心類,在該類中,我會加載新窗口,例如登錄窗口。

然后,每個窗口與應用程序上下文類來回對話。

我有一個用來打開新消息窗口的方法,就在這里。

public void InitiateChat(RosterItem Roster)
        {
            MessageWindow MessageWindow;
            if (WindowManager.ContainsKey(Roster.Jid.Bare) == false)
            {
                MessageWindow = new MessageWindow(Roster);
                MessageWindow.FormClosing += new FormClosingEventHandler(MessageWindow_FormClosing);

                //Store it.
                WindowManager.Add(Roster.Jid.Bare, MessageWindow);
            }
            else
            {
                MessageWindow = WindowManager[Roster.Jid.Bare];
            }

            if (MessageWindow.InvokeRequired)
            {
                MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat), new Object[] { Roster });
                return;
            }

            if (MessageWindow.WindowState == FormWindowState.Minimized)
            {
                MessageWindow.WindowState = FormWindowState.Normal;
            }
            MessageWindow.Show();
            MessageWindow.Activate();
        }

現在,當我從主Messenger窗口中的OnClick事件運行以下代碼時,它可以正常運行:

RosterItem RosterItem = GetSelectedContact();
if (RosterItem != null)
{
    Messenger.Bootload.MessengerApplication.Instnace.InitiateChat(RosterItem);
}

該窗口可以完美運行,但是由於這是基於XMPP和agsXMPP的Messenger應用程序,因此我有一個由agsXMPP觸發的事件,稱為OnMessage,該事件向我發送一條通知,告知我有傳入消息。

這就是這種方法。

public void ClientConnection_OnMessage(Object Sender, agsXMPP.protocol.client.Message Message) 
{
    //Load the contacts Window
    RosterItem RosterItem = ContactManager[Message.From.Bare];
    if (RosterItem != null)
    {
         InitiateChat(RosterItem);
    }
}

問題是當消息發出時,我運行了InitiateChat方法,但是它凍結了:(

它的MessageWindow.Show()無法正常運行

有人可以幫我解決這個問題嗎,我已經嘗試了幾天了。

您的OnMessage事件處理程序在后台線程上運行。 這在面向套接字的代碼中很常見。 該線程存在很多問題,它不運行消息循環並退出。 使表格變得緊張的兩個原因。

您必須封送對UI線程的表單創建方法調用。 通常用Control.BeginInvoke()完成。 由於您沒有明顯的Form對象充當BeginInvoke提供程序,因此您的操作有些棘手。 您將不得不使用System.Threading.SynchronizationContext.Current.Post()。 我將其保留為練習,使用主窗口而不是ApplicationContext將是更簡單的方法。

   if (MessageWindow.InvokeRequired)
   {
       MessageBox.Show("Invoking Window");
       MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat), 
           new Object[] { Roster });
       return;
   }

您正在從另一個線程調用MessageBox。 那行不通。

只需用System.Diagnostics.Debug.Print()或類似的東西替換MessageBox.Show(...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM