线程执行 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++;
}
}
}
}
一些注释行正在使用线程,但它会产生相同的结果。可能有什么问题?
因为您在 this.Invoke
中调用ping.Send
,Invoke
将在 UI 线程中同步执行委托,从而冻结 UI。
你应该在this.Invoke
之外做,或者使用await Ping.SendAsync
。当然,如果您打算等待,则需要以async
方法进行。在您的情况下,您需要一个async
lambda。