简体   繁体   中英

How to simplify multiple awaits with a single 'await Task.WhenAll'?

I assume that I have to use Task.WhenAll in the code below but cannot figure out hot it should be implemented properly.

Please, help.

 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;
        }

If you want both task to execute simultaneously, then don't await the methods. Instead pass their tasks into a variables and call them in 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;
}

Also note that you should avoid async void methods.

var calendarTask = GetCalendar(month, year, deviceTypeID);
var workTypesTask = GetWorkTypes(); 

Task.WaitAll(calendarTask, workTypesTask);
var calendar = await calendarTask;
var workTypes = await workTypesTask;

To answer @crazyGamer , the reason you do this is so that both tasks can run at the same time. Otherwise you're waiting for the first task before you even start working on the 2nd. Of course, if they depend on each other, that's a good thing. Otherwise, this'll tend to run faster on MP systems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM