winforms 表单未加载

ehxuflar  于 2023-01-26  发布在  其他
关注(0)|答案(2)|浏览(192)

在另一台计算机上的c# windows窗体应用程序中,您将看到一段代码,该代码用于查看名为textBox1的文本框中Rasberry pi的时间数据。运行时,print语句工作正常,但窗体无法加载。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;

namespace WindowsFormsApp4
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Console.WriteLine("Trying to establish connection...");
            TcpClient client = new TcpClient();
            client.Connect("192.168.104.15", 4900);
            Console.WriteLine("Connection established.");
            NetworkStream stream = client.GetStream();
            byte[] buffer = new byte[1];
            int bytesReceived;

            while (true)
            {
                bytesReceived = stream.Read(buffer, 0, buffer.Length);
                if (bytesReceived == 0)
                    break;

                Console.WriteLine("Data received.");
                string receivedData = System.Text.Encoding.ASCII.GetString(buffer, 0, bytesReceived);
                textBox1.Text += receivedData;
                Array.Clear(buffer, 0, buffer.Length);
                Console.WriteLine("Data printed.");
            }
            client.Close();
        }
    }
}

我在python和python之间也做了同样的处理,它运行得很好。我还没有为C#做任何具体的事情来解决这个问题。

mwngjboj

mwngjboj1#

while(true)

正在阻塞UI线程。因此加载窗体永远不会完成。尝试将while(true)放入新线程。因此Winform UI线程不会被阻塞。

xzabzqsa

xzabzqsa2#

您的代码显示尝试读取TCP连接,并且您的注解澄清了您"希望在无限循环中接收数据"。一种在不阻塞主窗体的load方法的情况下实现此结果的方法是使用async方法执行IO:

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        _tcpTask = execTcpPingLoop();
    }
    private Task? _tcpTask = null;
    private async Task execTcpPingLoop()
    {
        Console.WriteLine("Trying to establish connection...");
        using (TcpClient client = new TcpClient())
        {
            try
            {
                await client.ConnectAsync(
                    "192.168.104.15",
                    4900,
                    new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token
                );
                Console.WriteLine("Connection established.");
                byte[] buffer = new byte[1];
                int bytesReceived;

                while (true)
                {
                    using (NetworkStream stream = client.GetStream())
                    {
                        bytesReceived = await stream.ReadAsync(buffer, 0, buffer.Length);
                    }
                    if (!bytesReceived.Equals(0))
                    {
                        Console.WriteLine("Data received.");
                        string receivedData = System.Text.Encoding.ASCII.GetString(buffer, 0, bytesReceived);
                        textBox1.AppendText(receivedData);
                        Array.Clear(buffer, 0, buffer.Length);
                        Console.WriteLine("Data printed.");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, ex.Message);
            }
        }
    }
}
    • 测试**

由于我无法访问您的TCP连接,下面是我用来测试这个答案的代码:

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        _tcpTask = execTcpPingLoop();
    }
    private Task? _tcpTask = null;
    private async Task execTcpPingLoop()
    {
        Console.WriteLine("Trying to establish connection...");
        using (TcpClient client = new TcpClient())
        {
            try
            {
                richTextBox.Append("Trying to establish connection...", color: Color.Blue);
                while (true)
                {
                    var pingReply = new Ping().Send(
                    "www.google.com",
                    timeout: (int)TimeSpan.FromSeconds(10).TotalMilliseconds,
                    buffer: new byte[0],
                    options: new PingOptions(64, true));
                    richTextBox.Append($"{pingReply.Status}: Elapsed={pingReply.RoundtripTime}");
                    // Wait out the delay asynchronously
                    await Task.Delay(1000);
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, ex.Message);
            }
        }
    }
}

其中AppendRichTextBox的扩展名:

static class Extensions
{
    public static void Append(this RichTextBox @this, string? text = null, bool newLine = true, Color? color = null) 
    {
        if (newLine && !string.IsNullOrWhiteSpace(text))
        {
            text = $"{text}{Environment.NewLine}";
        }
        if (color != null)
        {
            var colorB4 = @this.ForeColor;
            @this.SelectionColor = (Color)color;    
            @this.AppendText(text);
            @this.SelectionColor = colorB4;  
        }
        else @this.AppendText(text);
    }
}

相关问题