Как визуализировать данные из консольного приложения c # в форме Windows? - PullRequest
0 голосов
/ 04 октября 2019

Я получаю данные с порта UDP, и нет проблем с отображением их в консоли. У меня проблема при попытке отправить эти данные в форму Windows и использовать их там. Вот мой код:

using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;

namespace ConsoleApp2 {
    class Program {
        static void Main(string[] args) {
            Console.WriteLine();
            Thread t = new Thread(FormDrawing);
            t.Start(UDPListener());
        }

        // Listening Port
        static byte[] UDPListener() {
            Console.WriteLine("Waiting for client");
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 162);
            EndPoint ep = (EndPoint)ipep;
            socket.Bind(ep);
            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
            byte[] indata = new byte[1024];
            IPEndPoint peer = new IPEndPoint(IPAddress.Any, 0);
            EndPoint inep = (EndPoint)peer;
            int inlen = socket.ReceiveFrom(indata, ref inep);
            socket.Close();
            Console.WriteLine(indata.ToString());
            return indata;
        }

        // Drawing Form
        static void FormDrawing(object ob) {
            byte[] obj = (byte[])ob;
            Form mainForm = new Form();
            if (obj != null) {
                Button MS2 = new Button {
                    Location = new Point(0, 0),
                    Size = new Size(80, 80),
                    Text = obj.ToString(),
                    BackColor = Color.Green
                };
                mainForm.Controls.Add(MS2);
            }
            mainForm.Show();
            Thread.Sleep(5000);
        }
    }
}

Окно открывается с какой-то кнопкой. Итак, obj не является нулевым. Но эта кнопка белая. Форма закрывается через 5 секунд. В чем может быть проблема?

Ответы [ 2 ]

0 голосов
/ 05 октября 2019

Помните до того момента, когда ваше приложение будет живым? Если в вашем приложении нет хотя бы одного основного потока.

При запуске приложения основной поток вводит метод Main(). Он получает байты из сокета и запускает новый поток, передавая эти байты в качестве аргумента. И тогда ваш основной поток завершается, но по мере того как вы создали ваше потоковое приложение foreground , оно все еще работает. Новый поток создает форму и показывает ее, но он не инициализирует цикл отправки сообщений, поэтому ваша форма не отображается полностью и ведет себя как приложение-обработчик - она ​​просто не обрабатывает никаких сообщений от пользователя (при наведении курсора, нажатии, перетаскивании и т. Д.). ). Тем временем вы замораживаете поток на 5 секунд, а затем он закрывается, ваше приложение закрывается.

Так что никаких проблем здесь нет, волшебства нет, все детерминировано и работает точно так, как вы его запрограммировали:)

Попробуйте использовать Application.Run(mainForm); или mainForm.ShowDialog() вместо mainForm.Show(). Эти методы запустят цикл обмена сообщениями приложения, и вы увидите открытую форму, пока не закроете ее. Подробнее о цикле обмена сообщениями в приложениях здесь .

Еще одно замечание: вы не устанавливаете квартиру в своем потоке пользовательского интерфейса. Прочитайте здесь подробнее, что это за хакерство. Пожалуйста, позвоните t.SetApartmentState(ApartmentState.STA);, прежде чем позвонить Start(). Другой вариант - пометить Main() на STAThreadAttribute и запустить форму, как я описал выше в вашем методе Main().

0 голосов
/ 04 октября 2019

Самый простой способ, вероятно, состоит в том, чтобы убедиться, что у вас установлена ​​последняя версия ядра dotnet, затем выполните dotnet new winforms из командной строки и используйте этот проект в качестве отправной точки.

Это даст вамосновной метод, подобный этому:

[STAThread]
static void Main()
{
    Application.SetHighDpiMode(HighDpiMode.SystemAware);
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

Как уже сказал Сандер, ваш код работает так, как вы ожидаете, то есть открывает, спит в течение 5 секунд и завершает работу. Я предполагаю, что вы видели такое же поведение в базовом консольном приложении и обошли его с помощью Console.ReadLine() ... то же самое применимо и здесь в некотором смысле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...