Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从套接字线程创建Window.Forms.Form_C#_Multithreading_Forms_Sockets_Applicationcontext - Fatal编程技术网

C# 如何从套接字线程创建Window.Forms.Form

C# 如何从套接字线程创建Window.Forms.Form,c#,multithreading,forms,sockets,applicationcontext,C#,Multithreading,Forms,Sockets,Applicationcontext,我正在编写一个小应用程序,它将作为NLog网络目标的端点(通过TCP发送调试消息)。该应用程序使用套接字创建服务器并接受连接。此应用程序是无窗口的,使用NotifyIcon和ApplicationContext在系统托盘中启动。应用程序侦听端口,当它从唯一端点接收到第一条消息时,它将创建一个新窗口并显示它(这些窗口将包含实际的调试消息)。我已经能够让窗口显示,但它的显示就像挂起一样,我猜这是因为它是从套接字创建的不可见线程中创建的 如何从test_ClientConnected事件正确创建新的W

我正在编写一个小应用程序,它将作为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());
    }
}
静态类程序
{
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
运行(新的NLApplicationContext());
}
}

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

您可以将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();
   }

终于找到了一种不同的方法,允许我在主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
    }
}
类NLApplicationContext:ApplicationContext { 列出_connections;//暂时临时存储 同步上下文测试; 公共NLApplicationContext() { 测试=SynchronizationContext.Current; _连接=新列表(); NLServer test=新的NLServer(); test.ClientConnected+=test\u ClientConnected; test.Start(); } 无效测试\u客户端已连接(对象发送方) { 测试。Post(显示表单、发送者); } 私有void显示表单(对象发送方) { Form2 newForm=新Form2((NLClient)发送方); newForm.Show(); _connections.Add(newForm);//查找更好的存储/排序 } }

使用SynchronizationContext允许我发回创建它的线程。

好的,我是否创建此调度程序?我找到的唯一引用是在WPF中使用的,可能我看错了。Hrmm…这确实有效,但是我需要它在主UI线程上运行,因为我在那里存储表单实例,表单列表,因为可能有一些连接。将此标记为应答,因为它是最接近的一个。你给我指出了正确的方向,谢谢。