Home > Enterprise >  Form does not load
Form does not load

Time:01-24

You are seeing a code written to see time data from Rasberry pi in a text box named textBox1 in a c# windows form application on another computer. When run, the print statements work fine but the form does not load.

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();
        }
    }
}

I did the same process from python to python, it was working fine. I haven't done anything specific to this problem for C#.

CodePudding user response:

The

while(true)

is blocking the UI thread. So the load form never finish. Try putting the while(true) to a new thread. so the Winform UI thread is not blocked.

CodePudding user response:

Your code shows an attempt read a TCP connection and your comment clarifies that you "want to receive data in an infinite loop". One way to achieve this outcome without blocking the main form's load method is to do your IO using async methods:

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void onl oad(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);
            }
        }
    }
}

Test

Since I don't have access to your TCP connection, here's the code I used to test this answer:

screenshot

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void onl oad(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);
            }
        }
    }
}

Where Append is an extension for RichTextBox:

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);
    }
}
  • Related