C# 线程和窗体。Show()
我似乎在穿线方面有困难 首先让我解释一下应用程序是如何构建的 我有一个扩展ApplicationContext的类,它是我整个应用程序的核心类,在这个类中我加载新窗口,比如登录窗口 然后每个窗口与应用程序上下文类来回对话 我有一个方法用来打开一个新的消息窗口,在这里C# 线程和窗体。Show(),c#,winforms,multithreading,show,C#,Winforms,Multithreading,Show,我似乎在穿线方面有困难 首先让我解释一下应用程序是如何构建的 我有一个扩展ApplicationContext的类,它是我整个应用程序的核心类,在这个类中我加载新窗口,比如登录窗口 然后每个窗口与应用程序上下文类来回对话 我有一个方法用来打开一个新的消息窗口,在这里 public void InitiateChat(RosterItem Roster) { MessageWindow MessageWindow; if (Windo
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()不能正常运行
有谁能帮我实现这一点吗,我已经尝试了几天了。你可以在后台线程上运行消息事件处理程序。这在面向套接字的代码中很常见。该线程有很多问题,它不运行消息循环,并且它退出。两个原因使表单变得紧张
您必须封送对UI线程的表单创建方法调用。这通常是通过Control.BeginInvoke()完成的。在您的情况下有点棘手,因为您没有明显的表单对象作为BeginInvoke提供程序。您必须使用System.Threading.SynchronizationContext.Current.Post()进行处理。我将这作为一个练习,使用主窗口而不是应用程序上下文将是更简单的方法。您可以在后台线程上运行消息事件处理程序。这在面向套接字的代码中很常见。该线程存在很多问题,它不运行消息循环,并且会退出。导致表单瘫痪的两个原因
if (MessageWindow.InvokeRequired)
{
MessageBox.Show("Invoking Window");
MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat),
new Object[] { Roster });
return;
}
您必须封送对UI线程的表单创建方法调用。这通常是通过Control.BeginInvoke()完成的。在您的情况下有点棘手,因为您没有明显的表单对象作为BeginInvoke提供程序。您必须使用System.Threading.SynchronizationContext.Current.Post()进行处理。我将把它作为练习,使用主窗口而不是应用程序上下文将是更简单的方法
if (MessageWindow.InvokeRequired)
{
MessageBox.Show("Invoking Window");
MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat),
new Object[] { Roster });
return;
}
您正在从另一个线程调用MessageBox。这不起作用
只需将MessageBox.Show(…)替换为System.Diagnostics.Debug.Print()或类似的内容
您正在从另一个线程调用MessageBox。这不起作用
只需将MessageBox.Show(…)替换为System.Diagnostics.Debug.Print()或者类似的东西。是的,我对后台线程也有同样的想法,所以基本上你说的不是我的应用程序类在尝试设置表单,而是后台线程,我对当前的.Post()一无所知实体,我将尝试研究一下。关于从bg线程初始化/调用表单,是否有一些示例可以链接到我?-您的信息非常有用,请使用应用程序。OpenForms[0]。BeginInvoke()如果你真的必须这样做的话。是的,我也考虑了很多关于后台线程的问题,所以基本上你说的不是我的应用程序类在尝试设置表单,而是后台线程,我对当前的.Post()一无所知实体,我将尝试研究一下。关于从bg线程初始化/调用表单,是否有一些示例可以链接到我?-您的信息非常有用,请使用应用程序。OpenForms[0]。BeginInvoke(),如果必须的话。是的,Egnore MessageBox.Show()那是我刚刚测试的,看看是不是调用问题导致了它,但不是。是jsut TEMPYAE,Egnore MessageBox.Show()我刚刚测试的,看看是不是调用问题导致了它,但不是。是jsut temp