我试图从后台线程(我认为)打开一个Form,因为当我调用formName.Show();形式冻结(不是主要形式)。
目标:
当用户收到新消息时,弹出带有新消息的newMessageFrm进行回复。
问题:
新表单锁定。
以下是我正在使用的代码:
static void OnNewMessage(object sender, S22.Xmpp.Im.MessageEventArgs e)
{
if(CheckIfFormIsOpen(e.Jid.ToString(), e.Message.ToString()) == true){
} else
{
newMessageFrm tempMsg = new newMessageFrm(e.Jid.ToString());
tempMsg._msgText = e.Jid.ToString() + ": " + e.Message.ToString();
tempMsg.frmId = e.Jid.ToString();
tempMsg.Show(); //This locks up the application
}
}
我正在使用Visual Studio 2015,C#和S22.Xmpp(正如您从代码中看到的那样。)
当此事件触发时,表单会弹出,但随后会锁定。
如果您需要更多信息,请与我们联系。
答案 0 :(得分:2)
不幸的是,我不知道在没有任何现有表格的情况下如何做到这一点。但我相信你有一些你可以访问的主要形式。或者您可以使用
获取Form
var invokingForm = Application.OpenForms[0];
所以你可以改变你的方法代码:
static void OnNewMessage(object sender, S22.Xmpp.Im.MessageEventArgs e)
{
var invokingForm = Application.OpenForms[0]; // or whatever Form you can access
if (invokingForm.InvokeRequired)
{
invokingForm.BeginInvoke(new EventHandler<S22.Xmpp.Im.MessageEventArgs>(OnNewMessage), sender, e);
return; // important!!!
}
// the rest of your code goes here, now running
// on the same ui thread as invokingForm
if(CheckIfFormIsOpen(e.Jid.ToString(), e.Message.ToString()) == true)
{
}
else
{
newMessageFrm tempMsg = new newMessageFrm(e.Jid.ToString());
tempMsg._msgText = e.Jid.ToString() + ": " + e.Message.ToString();
tempMsg.frmId = e.Jid.ToString();
tempMsg.Show();
}
}
请注意,我保留S22.Xmpp.Im.MessageEventArgs
继承自System.EventArgs
。
答案 1 :(得分:2)
在WinForms中,仍然需要UI对象需要位于带有消息泵的线程上。这通常是主应用程序线程,也称为UI线程。
在Winforms中检查您是否在使用Control.InvokeRequired
访问UI对象的正确线程上。如果返回true,则表示您没有使用正确的线程,并且需要使用Invoke操作。
既然你知道自己是一个不同的主题,你就不需要检查,你只需要调用。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(BadBackgroundLaunch);
ThreadPool.QueueUserWorkItem(GoodBackgroundLaunch);
}
private void GoodBackgroundLaunch(object state)
{
this.Invoke((Action) (() =>
{
var form2 = new SecondForm();
form2.Text = "Good One";
form2.Show();
}));
}
private void BadBackgroundLaunch(object state)
{
var form2 = new SecondForm();
form2.Text = "Bad one";
form2.Show();
}
}