【问题标题】:Timer not working in a simple UDP chat application in c#计时器在 c# 中的简单 UDP 聊天应用程序中不起作用
【发布时间】:2022-12-22 00:51:49
【问题描述】:

我正在 C# winforms 上使用 udp 编写一个简单的聊天应用程序。

规则:

  1. 收到消息后,您有10秒的回复时间。
  2. 发布回复后,其他用户有 10 秒的时间回复。
  3. Sender 提供控制权,OtherPeopleTimer 计算时间并每秒将进度条值减少 10(Sender 端的进度条),如果时间用完惩罚方法将运行。
  4. 在接收方,OursTimer 每秒将进度值减少 10,仅供参考,并在时间用完时停止,不执行任何操作。

    通过运行相同的程序 exe,它将在同一台计算机上作为本地主机运行。

    Thread 负责监听传入的数据包并将传入的字符串发送到 ProcessIncomingData 函数。

    但是,计时器无法正常工作(您可以在进度条上跟踪这一点)。例如,当第一个 exe 发送消息时,第二个 exe 的进度条只减少一次,而它应该一直运行到进度条值为 0。

    这个问题的原因是什么,如何解决?

    代码:

    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:

    右边表格的进度条值每秒都在减少,而左边表格只减少一次并卡在那里。

    我想知道为什么正确表格上的进度条卡住了,我该如何解决这个问题。

【问题讨论】:

    标签: c# winforms timer udp


    【解决方案1】:

    在C#语言中,GUI操作应该由核心线程来管理,如果用额外的线程改变控件就会发生冲突。 为了避免这个问题;

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

    应该使用方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-03
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      相关资源
      最近更新 更多