Windows form freezes when using synchronous TCP Client

Viewed 41

I am writing a Windows Forms application in C# (single thread). The application uses a synchronous TCP client that connects to a remote server and messages are passed both ways (via a socket). The client sends a message and the server should respond with a message. The form is populated with network information (Textboxes), such as IP address, port number etc. This all works as expected and I can pass messages over the network.

But I have observed that the application sometimes becomes unresponsive for a moment, e.g. when trying to connect to an unreachable IP address. I have tried to investigate and it seems to me that the solution is to either use classical threading or to switch to an asynchronous TCP client, in order not to block the UI thread. I would like to try the asynchronous client, but I am not sure how this should be implemented.

Currently I connect, send and receive synchronously. Should it be possible to "just” add the async keywork to the method declarations and add the await keywork before the stream.Read or stream.Write?

I have seen various methods such as TcpClient.ConnectAsync, NetworkStream.BeginRead, NetworkStream.BeginWrite, NetworkStream.ReadAsync and NetworkStream.WriteAsync with various different examples, so I am confused about which methods to use and how to use them.

My code:

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

NetworkStream stream;
TcpClient client;
int port;

//Button click event to connect with the server from the client
private void btn_Connect_Click(object sender, EventArgs e)
    {
        if (!int.TryParse(txtBox_Port.Text, out port))
        {
            MessageBox.Show("Port number not valid.");
        }
            try
            {
                client = new TcpClient(txtBox_IP_Addr.Text, port);
                //UI "hangs/freezes" for several seconds if this connection cannot be established
                txtBox_Connection_Status.Text = "Connection made with " + txtBox_IP_Addr.Text + " on port " + txtBox_Port.Text;
            }
            catch
            {
                txtBox_Connection_Status.Text = "Connection not established";
            }
    } 

//Button click event to send data from the client to the server and receive response from the server
private void btn_Send_Click(object sender, EventArgs e)
    {
        try
            {
                byte[] message = { 0x00, 0x07 };
                stream = client.GetStream();
                stream.Write(message, 0, message.Length);
            }
        catch
            {
                txtBox_Connection_Status.Text = "No connection";
            }
        try
            {
                byte[] buffer = new byte[4096];
                int no_read_bytes = stream.Read(buffer, 0, buffer.Length);
                //UI "hangs/freezes" if no data is received
            }
        catch
            {
                txtBox_Connection_Status.Text = "No connection";
            }
    }
0 Answers
Related