Home > Back-end >  Timer not working in a simple UDP chat application in c#
Timer not working in a simple UDP chat application in c#

Time:12-22

I am writing a simple chat application using udp on C# winforms.

Rules:

  1. After receiving a message, you have 10 seconds to reply.
  2. After posting a reply, the other user has 10 seconds to reply.
  3. Sender provides control and OtherPeopleTimer calculates the time and decreases the progressbar value by 10 every second (progressbar on Sender side), if time runs out penalty method will run.
  4. On the receiving side, OursTimer decreases the progress value by 10 every second for information purposes only, and stops when the time runs out, does nothing.

By running the same program exe, it will be run as localhost on the same computer.

Thread is responsible for listening for incoming packets and sending the incoming string to the ProcessIncomingData function.

However, the timers do not work correctly (you can track this on the progressbar). For example, when the 1st exe sends a message, the progressbar on the 2nd exe decreases only once, whereas it should run until the progressbar value is 0.

What is the cause of this problem and how to solve it?

The code:

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

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        IPAddress ServerIP;
        int ServerPort;
        IPEndPoint ServerEndPoint;
        Socket ServerSocket;

        IPAddress ClientIP;
        int ClientPort;
        IPEndPoint ClientEndPoint;

        Thread Listener;

        private void Form1_Load(object sender, EventArgs e)
        {
            OursTimer.Interval= 1000;
            OtherPeopleTimer.Interval= 1000;
            OursTimer.Enabled = false;
            OtherPeopleTimer.Enabled = false;

            ClientIP = IPAddress.Parse("127.0.0.1");
            ClientPort = 20000;
            ClientEndPoint = new IPEndPoint(ClientIP, ClientPort);


            ServerIP = IPAddress.Parse("127.0.0.1");
            ServerPort = 10000;
            ServerEndPoint = new IPEndPoint(ServerIP, ServerPort);

            ServerSocket = new Socket(SocketType.Dgram, ProtocolType.Udp);

            try
            {
                ServerSocket.Bind(ServerEndPoint);
            }
            catch (Exception)
            {
                ServerPort = 20000;
                ServerEndPoint = new IPEndPoint(ServerIP, ServerPort);
                ServerSocket.Bind(ServerEndPoint);
                ClientPort = 10000;
            }

            Listener = new Thread(Listen);
            Listener.Start();

        }
        public void Listen()
        {
            while (true)
            {
                byte[] buffer = new byte[1024];
                ServerSocket.Receive(buffer);

                string incomingMessage = Encoding.UTF8.GetString(buffer);
                incomingMessage = incomingMessage.Substring(0, incomingMessage.IndexOf("\0"));

                ProcessIncomingData(incomingMessage);
            }
            
        }
        public void ProcessIncomingData(string message)
        {
            OtherPeopleTimer.Stop();
            progressBar1.Value = 100;
            OursTimer.Start();
            MessageBox.Show(message);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            OursTimer.Stop();
            byte[] buffer = Encoding.UTF8.GetBytes(textBox1.Text);
            ServerSocket.SendTo(buffer, ClientEndPoint);
            progressBar1.Value = 100;
            OtherPeopleTimer.Start();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Environment.Exit(0);
        }
        private void OursTimer_Tick(object sender, EventArgs e)
        {
            if (progressBar1.Value > 0)
                progressBar1.Value -= 10;
            else
                OursTimer.Stop();
        }

        private void OtherPeople_Tick(object sender, EventArgs e)
        {
            if (progressBar1.Value > 0)
                progressBar1.Value -= 10;
            else
                OtherPeopleTimer.Stop();
        }
    }
}

Output:

While the progressbar value on the right form decreases every second, the left form decreases only once and gets stuck there.

I want to know why the progressbar on the right form is stuck and how I can solve this problem.

CodePudding user response:

In C# language, GUI operations should be managed by core threads, conflicts will occur if controls are changed with additional threads. To avoid this problem;

this.Invoke((MethodInvoker)delegate
            {
                //code
            });

method should be used.

  • Related