我正在编写一个小应用程序,它将成为NLog网络目标的终端(通过TCP发送调试消息)应用程序使用套接字创建服务器并接受连接。此应用程序是无窗口的,使用NotifyIcon和ApplicationContext在系统托盘中启动。应用程序侦听端口,当它从唯一的端点收到它的第一条消息时,它将创建一个新窗口并显示它(这些窗口将包含实际的调试消息)我已经能够显示窗口但它正在显示好像它已挂起,我猜它是因为它是从套接字创建的不可见线程创建的。
如何从test_ClientConnected事件中正确创建新的Windows.Form?
这是ApplicationContext代码
public NLApplicationContext()
{
NLServer test = new NLServer();
test.ClientConnected += test_ClientConnected;
test.Start();
}
void test_ClientConnected(object sender)
{
Form2 newForm = new Form2((NLClient)sender);
newForm.Invoke(new MethodInvoker(() => {newForm = new Form2((NLClient)sender);}));
newForm.Invoke(new MethodInvoker(() => { newForm.Show(); }));
Console.WriteLine("Connected");
/*if (((NLClient)sender).testy.InvokeRequired)
{
((NLClient)sender).testy.BeginInvoke(new MethodInvoker(((NLClient)sender).testy.Show()));
return;
}*/
}
这是程序入口点
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new NLApplicationContext());
}
}
答案 0 :(得分:0)
你有正确的想法,而不是在套接字线程中创建表单,移动代码来创建表单并将其显示到方法中,然后Dispatcher.Invoke
在UI线程上执行它的方法。 / p>
答案 1 :(得分:0)
您可以将UI工作委托给一个单独的线程,如下所示:
void test_ClientConnected(object sender)
{
Thread displayFormThread = new Thread(ParameterizedThreadStart(DisplayForm));
displayFormThread.Start(sender);
}
private void DisplayForm(object sender)
{
Form2 newForm = new Form2((NLClient)sender);
newForm.Show();
}
答案 2 :(得分:0)
最后想出了一种允许我在主UI线程中创建表单的不同方式。
NLApplicationContext
class NLApplicationContext : ApplicationContext
{
List<Form2> _connections; // Temp storage for now
SynchronizationContext testS;
public NLApplicationContext()
{
testS = SynchronizationContext.Current;
_connections = new List<Form2>();
NLServer test = new NLServer();
test.ClientConnected += test_ClientConnected;
test.Start();
}
void test_ClientConnected(object sender)
{
testS.Post(DisplayForm, sender);
}
private void DisplayForm(object sender)
{
Form2 newForm = new Form2((NLClient)sender);
newForm.Show();
_connections.Add(newForm); //Find better storage/sorting
}
}
使用SynchronizationContext允许我回发到它创建的线程。