NoWar
NoWar

Reputation: 37633

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

Upvotes: 0

Views: 4982

Answers (2)

zzxyz
zzxyz

Reputation: 2981

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.

Upvotes: 2

Nkosi
Nkosi

Reputation: 247088

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.

Upvotes: 10

Related Questions