【发布时间】:2017-04-01 11:59:22
【问题描述】:
我有一个扫描给定网络并返回有效 IP 地址的 WinForms 项目。找到所有地址后,我为每个地址创建一个用户控件并将其放置在表单上。我的 ping ip 地址函数使用 async 和 Task 我认为在执行其他操作之前会“等待”执行,但事实并非如此。我的表单显示为空白,然后在 5 秒内,所有用户控件都出现在表单上。
声明:
private List<string> networkComputers = new List<string>();
这是 Form_Load 事件:
private async void MainForm_Load(object sender, EventArgs e)
{
//Load network computers.
await LoadNetworkComputers();
LoadWidgets();
}
LoadNetworkComputers 函数在这里:
private async Task LoadNetworkComputers()
{
try
{
if (SplashScreenManager.Default == null)
{
SplashScreenManager.ShowForm(this, typeof(LoadingForm), false, true, false);
SplashScreenManager.Default.SetWaitFormCaption("Finding computers");
}
else
Utilities.SetSplashFormText(SplashForm.SplashScreenCommand.SetLabel, "Scanning network for computers. This may take several minutes...");
networkComputers = await GetNetworkComputers();
}
catch (Exception e)
{
MessageBox.Show(e.Message + Environment.NewLine + e.InnerException);
}
finally
{
//Close "loading" window.
SplashScreenManager.CloseForm(false);
}
}
最后两个函数:
private async Task<List<string>> GetNetworkComputers()
{
networkComputers.Clear();
List<string> ipAddresses = new List<string>();
List<string> computersFound = new List<string>();
for (int i = StartIPRange; i <= EndIPRange; i++)
ipAddresses.Add(IPBase + i.ToString());
List<PingReply> replies = await PingAsync(ipAddresses);
foreach(var reply in replies)
{
if (reply.Status == IPStatus.Success)
computersFound.Add(reply.Address.ToString());
}
return computersFound;
}
private async Task<List<PingReply>> PingAsync(List<string> theListOfIPs)
{
var tasks = theListOfIPs.Select(ip => new Ping().SendPingAsync(ip, 2000));
var results = await Task.WhenAll(tasks);
return results.ToList();
}
我真的很困惑为什么在MainForm_Load 事件中的代码完成之前显示表单。
编辑
我忘了提到在LoadNetworkComputers 中它加载了一个启动表单,让用户知道应用程序正在运行。当表格出现在其后面时,我试图避免。这是一个屏幕截图(敏感信息已被涂黑):
【问题讨论】:
-
也许我遗漏了一些东西,但 async/await 的全部目的并不是让您的代码在进行长时间操作时继续执行?
标签: c# multithreading thread-safety async-await task