Я делаю многопоточный тест-тестер.
Итак, я добавил несколько элементов управления ListView ListView и сделал один BackgroundWorkers для каждого элемента. В конце концов, я начал программу, и когда я начал пингу, основные формы формы управления застряли и не отвечали до тех пор, пока все ping-end (включая время просрочки). Вот весь источник. (Я разработал форму с графическим интерфейсом Form Designer)
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++;
}
}
}
}
В некоторых комментариях используются Threads, но он делает тот же результат. Что может быть проблемой?
Поскольку вы вызываете ping.Send
внутри this.Invoke
, Invoke
будет выполнять делегат синхронно в потоке пользовательского интерфейса и, таким образом, он замораживает пользовательский интерфейс.
Вы должны делать это за пределами this.Invoke
или использовать await Ping.SendAsync
. Конечно, если вы планируете ждать, вам нужно сделать это в async
методе. В вашем случае вам нужна async
лямбда.