如何用一个 'await Task.WhenAll' 简化多个等待?
How to simplify multiple awaits with a single 'await Task.WhenAll'?
我假设我必须在下面的代码中使用 Task.WhenAll
但无法弄清楚它应该正确实现。
拜托,帮忙。
public async void UpdateData()
{
var month = (cbMonths.SelectedItem as MonthView).ID;
var year = (cbYears.SelectedItem as YearView).ID;
var deviceTypeID = (int)DeviceType;
var calendar = await GetCalendar(month, year, deviceTypeID);
var workTypes = await GetWorkTypes();
if (calendar != null && workTypes != null) // Task.WhenAll ???
{
//...
}
}
private async Task<List<WorkTypeItem>> GetWorkTypes()
{
try
{
HttpClient client = new HttpClient();
var url = Properties.Settings.Default.ServerBaseUrl + @"/api/staff/WorkTypes";
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode) // Check the response StatusCode
{
var serSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };
string responseBody = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<List<MSOCommon.WorkTypeItem>>(responseBody, serSettings);
}
else
{
logger.Error(Properties.Resources.DATACannotGetWorkTypes);
}
}
catch (Exception ex)
{
logger.Error(Properties.Resources.DATACannotGetWorkTypes + " " + ex.Message);
}
return null;
}
如果您希望两个任务同时执行,则不要 await
这些方法。而是将他们的任务传递给变量并在 Task.WhenAll
中调用它们
public async Task UpdateData() {
var month = (cbMonths.SelectedItem as MonthView).ID;
var year = (cbYears.SelectedItem as YearView).ID;
var deviceTypeID = (int)DeviceType;
var task1 = GetCalendar(month, year, deviceTypeID);
var task2 = GetWorkTypes();
await Task.WhenAll(task1, task2);
var calendar = task1.Result;
var workTypes = task2.Result;
}
另请注意,您应避免使用 async void
方法。
var calendarTask = GetCalendar(month, year, deviceTypeID);
var workTypesTask = GetWorkTypes();
Task.WaitAll(calendarTask, workTypesTask);
var calendar = await calendarTask;
var workTypes = await workTypesTask;
回答@crazyGamer,你这样做的原因是两个任务可以同时运行。否则你甚至在开始第二个任务之前就在等待第一个任务。当然,如果他们互相依赖,那是好事。否则,这将 运行 在 MP 系统上更快。
我假设我必须在下面的代码中使用 Task.WhenAll
但无法弄清楚它应该正确实现。
拜托,帮忙。
public async void UpdateData()
{
var month = (cbMonths.SelectedItem as MonthView).ID;
var year = (cbYears.SelectedItem as YearView).ID;
var deviceTypeID = (int)DeviceType;
var calendar = await GetCalendar(month, year, deviceTypeID);
var workTypes = await GetWorkTypes();
if (calendar != null && workTypes != null) // Task.WhenAll ???
{
//...
}
}
private async Task<List<WorkTypeItem>> GetWorkTypes()
{
try
{
HttpClient client = new HttpClient();
var url = Properties.Settings.Default.ServerBaseUrl + @"/api/staff/WorkTypes";
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode) // Check the response StatusCode
{
var serSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All };
string responseBody = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<List<MSOCommon.WorkTypeItem>>(responseBody, serSettings);
}
else
{
logger.Error(Properties.Resources.DATACannotGetWorkTypes);
}
}
catch (Exception ex)
{
logger.Error(Properties.Resources.DATACannotGetWorkTypes + " " + ex.Message);
}
return null;
}
如果您希望两个任务同时执行,则不要 await
这些方法。而是将他们的任务传递给变量并在 Task.WhenAll
public async Task UpdateData() {
var month = (cbMonths.SelectedItem as MonthView).ID;
var year = (cbYears.SelectedItem as YearView).ID;
var deviceTypeID = (int)DeviceType;
var task1 = GetCalendar(month, year, deviceTypeID);
var task2 = GetWorkTypes();
await Task.WhenAll(task1, task2);
var calendar = task1.Result;
var workTypes = task2.Result;
}
另请注意,您应避免使用 async void
方法。
var calendarTask = GetCalendar(month, year, deviceTypeID);
var workTypesTask = GetWorkTypes();
Task.WaitAll(calendarTask, workTypesTask);
var calendar = await calendarTask;
var workTypes = await workTypesTask;
回答@crazyGamer,你这样做的原因是两个任务可以同时运行。否则你甚至在开始第二个任务之前就在等待第一个任务。当然,如果他们互相依赖,那是好事。否则,这将 运行 在 MP 系统上更快。