我正在将项目添加到FlowLayoutPanel中。每个项目都对IP地址进行ping测试,并发布其是向上还是向下。我遇到的问题:在每个项目都有结果之前,没有任何内容被发布到FlowLayoutPanel。我希望每个项目在完成后发布,而不是等待所有项目完成。我在想可能有办法使用线程来做到这一点?我现在还不太确定。一些指导会很棒!以下是foreach循环的样子:
string[] ipList = ipListTextBox.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
statusFlowPanel.Controls.Clear();
statusFlowPanel.Controls.Add(p1);
foreach (string ip in ipList)
{;
Label ipAddressLabel = new Label();
ipAddressLabel.Text = ip;
Label statusLabel = new Label();
statusLabel.Text = "Status: ";
statusLabel.Location = new Point(20, 10 + x);
PictureBox updownPicBox = new PictureBox();
updownPicBox.Height = 30;
updownPicBox.Width = 30;
updownPicBox.Location = new Point(80, 0);
Ping pingSender = new Ping();
IPAddress address = IPAddress.Parse(ip);
PingReply reply = pingSender.Send(address);
if (reply.Status == IPStatus.Success)
{
updownPicBox.Image = Properties.Resources.up_arrow;
}
else
{
updownPicBox.Image = Properties.Resources.down_arrow;
}
var ipPanel = new Panel();
//Invoke(new Action(() => ));
statusFlowPanel.Controls.Add(ipPanel);
ipPanel.Controls.Add(updownPicBox);
ipPanel.Controls.Add(statusLabel);
ipPanel.Controls.Add(ipAddressLabel);
ipPanel.Height = 40;
x++;
}
答案 0 :(得分:0)
有许多方法可以解决这个问题。
这应该让你知道要采取的方向,应该在.net 4.0+下工作 - 注意主/ UI线程正在等待循环完成,所以你没有响应的UI,而这是发生了,但是这段代码会创建一个List<Task>
,因此您可以按照自己喜欢的方式运行它们:
private Panel GetStatusPanel(string ip)
{
var result = new Panel();
result.Controls.Add(new Label { Text = ip });
Thread.Sleep(1000); // do the ping here, populate result panel accordingly
return result;
}
private void button1_Click(object sender, EventArgs e)
{
var ipList = new List<string> { "127.0.0.1", "192.168.0.1", "whatever" };
statusFlowPanel.Controls.Clear();
var tasks = ipList.Select(ip => new Task(() =>
BeginInvoke((MethodInvoker)delegate
{
statusFlowPanel.Controls.Add(GetStatusPanel(ip));
statusFlowPanel.Refresh();
}))
).ToList();
tasks.ForEach(t => t.Start());
}
这会在ping结果进入时将状态面板添加到statusFlowPanel
。