0

NLogネットワークターゲットのエンドポイントとなる小さなアプリを作成しています(TCPを介したデバッグメッセージの送信)このアプリは、ソケットを使用してサーバーを作成し、接続を受け入れます。このアプリケーションはウィンドウがなく、NotifyIconとApplicationContextを使用してシステムトレイで起動します。アプリケーションはポートでリッスンし、一意のエンドポイントから最初のメッセージを受信すると、新しいウィンドウを作成して表示します(これらのウィンドウには実際のデバッグメッセージが含まれます)ウィンドウを表示することはできましたが、表示されていますハングしているように、Socketsによって作成された非表示のスレッドから作成されているためだと思います。

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

最後に、メイン 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 に答える
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 に答える