0

我正在编写一个小型应用程序,它将成为 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());
    }
}
4

3 回答 3

0

您有正确的想法,而不是在套接字线程中创建表单,而是移动代码以创建表单并将其显示到一个方法中,然后Dispatcher.Invoke在 UI 线程上执行它的方法。

于 2013-01-05T15:08:13.050 回答
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();
   }
于 2013-01-05T15:46:23.827 回答
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 允许我回发到创建它的线程。

于 2013-01-05T16:11:09.233 回答