线程执行 Ping 测试时主窗体卡住

本文关键字:窗体 执行 Ping 测试 线程 | 更新日期: 2023-09-27 18:34:31

我正在制作基于多线程的ping测试器。

因此,我向 ListView 控件添加了一些 IP,并为每个项目制作了一个 BackgroundWorkers。毕竟,我启动了程序,当我开始ping时,主窗体的表单控件卡住了,直到所有ping结束才响应(包括过期的ping(。这是整个来源。(我使用表单设计器 GUI 设计表单(

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Net.NetworkInformation;
namespace Multi_Ping_Tester
{
    public partial class frmMain : Form
    {
        //List<Thread> pingThreads = new List<Thread>();
       private void doPing(object sender, DoWorkEventArgs e)
        {
            Ping pingsender = new Ping();
            PingReply pingres;
            int idx = (int)e.Argument;
            this.Invoke(new MethodInvoker(delegate()
            {
                string addr = lvwIPList.Items[idx].Text;
                //do
                //{
                pingres = pingsender.Send(addr);
                if (pingres.Status == IPStatus.Success)
                {
                    lvwIPList.Items[idx].SubItems[1].Text = pingres.RoundtripTime.ToString();
                    lvwIPList.Items[idx].BackColor = Color.LightGreen;
                }
                else
                {
                    lvwIPList.Items[idx].SubItems[1].Text = "Nein";
                    lvwIPList.Items[idx].BackColor = Color.LightPink;
                }
                //} while(true);
            }));
        }

        List<BackgroundWorker> bgwList = new List<BackgroundWorker>();
        private void ResizeCol()
        {
            chdIP.Width = (int)((lvwIPList.Width - 6) * 0.8);
            chdRTT.Width = (int)((lvwIPList.Width - 6) * 0.2);
        }
        public frmMain()
        {
            InitializeComponent();
        }
        private void frmMain_Load(object sender, EventArgs e)
        {
            ResizeCol();
        }
        private void btnAdd_Click(object sender, EventArgs e)
        {
            lvwIPList.Items.Add(txtIP.Text);
            lvwIPList.FindItemWithText(txtIP.Text).SubItems.Add("");
        }
        private void btnPing_Click(object sender, EventArgs e)
        {
 /*           pingThreads.Clear();
            int idx=0;
*/
            bgwList.Clear();
            int idx = 0;
            foreach (ListViewItem i in lvwIPList.Items)
            {
                /*
                pingThreads.Add(new Thread(new ParameterizedThreadStart(doPing)));
                pingThreads[idx].IsBackground = true;
                pingThreads[idx].Start(idx);
                idx++;
                */
                bgwList.Add(new BackgroundWorker());
                bgwList[idx].DoWork += new DoWorkEventHandler(doPing);
                bgwList[idx].RunWorkerAsync(idx);
                idx++;
            }
        }
    }
}

一些注释行正在使用线程,但它会产生相同的结果。可能有什么问题?

线程执行 Ping 测试时主窗体卡住

因为您在 this.Invoke 中调用ping.SendInvoke将在 UI 线程中同步执行委托,从而冻结 UI。

你应该在this.Invoke之外做,或者使用await Ping.SendAsync。当然,如果您打算等待,则需要以async方法进行。在您的情况下,您需要一个async lambda。