【发布时间】:2018-11-08 13:31:30
【问题描述】:
在我的 OnNavigatedTo 方法中 ViewModel 类的 Prism 模块中
我想用多个异步调用的结果填充 ObservableCollection,而不是等待所有调用完成。
我正在使用这个问题的答案: How to hydrate a Dictionary with the results of async calls?
以下代码是我真实代码的清理版:
我的身份等级:
public class Status
{
public string ipAddress;
public string status;
}
我的视图模型:
using Prism.Mvvm;
using Prism.Regions;
public class StatusViewModel : BindableBase, INavigationAware
{
ObservableCollection<Status> statusCollection = new ObservableCollection<Status>();
HttpClient httpClient = new HttpClient();
Ping ping = new Ping();
List<string> ipAddressList = new List<string>();
public void OnNavigatedTo(NavigationContext navigationContext)
{
GetEveryStatus();
}
public void GetEveryIp() // this is not important, works ok
{
var addressBytes = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork).GetAddressBytes();
for (byte i = 1; i < 255; ++i)
{
addressBytes[3] = i;
string ipAddress = new IPAddress(addressBytes).ToString();
if (ping.Send(ipAddress, 10).Status == IPStatus.Success)
{
ipAddressList.Add(ipAddress);
}
}
}
public void GetEveryStatus() // this is important, here is the problem
{
GetEveryIp();
var task = GetStatusArray(ipAddressList);
statusCollection.AddRange(task.Result);
}
// solution from stackoverflow, but it throws exception
public async Task<Status[]> GetStatusArray(List<string> ipAddressList)
{
Status[] statusArray = await Task.WhenAll(
ipAddressList.Select(
async ipAddress => new Status(
ipAddress,
await httpClient.GetStringAsync("http://" + ipAddress + ":8080" + "/status")
)
)
);
return statusArray;
}
}
但这不起作用,因为 GetStringAsync 可以抛出异常,所以我将其更改为:
public void GetEveryStatus() // this is important, here is the problem
{
GetEveryIp();
foreach (string ipAddress in ipAddressList)
{
try
{
var task = httpClient.GetStringAsync("http://" + ipAddress + ":8080" + "/status");
statusCollection.Add(new Status(ipAddress, task.Result));
}
catch (Exception)
{
}
}
}
但还是不行。
这样做的正确方法是什么?谢谢!
【问题讨论】:
-
阅读
Task.Result的文档并告诉我们task.Wait(10);在task.Result之前的意义是什么? -
为什么不让 GetEveryStatus 异步?并使用 await 代替 task.Wait()
-
@Selvin "表示等待毫秒数的 TimeSpan,或表示无限期等待 -1 毫秒的 TimeSpan。"我用错了吗?我想等待 10 毫秒让 GetStringAsync 完成?
-
Task.Result的文档(查看备注部分)不是Task.Wait -
@AccessDenied OnNavigatedTo 不是异步的,它是 INavigationAware 的实现
标签: c# mvvm async-await task-parallel-library observablecollection