Best location to place await when Task.WhenAll used

Kumara Prathipati 1 Reputation point
2022-02-20T02:37:05.243+00:00

We are calling 2 methods
both methods return similar data type <string>

Task.WhenAll returns a string array.

What is the best place to await.

Line 3 pattern

or

Line 4 + 5 pattern

or

Line 6 + 7 pattern

What is the reason for choosing one over the other pattern?

Appreciate any help.

Line 1. Task<string> t1 = SomeMethod_A_ToCallStoredProcedure();
Line 2. Task<string> t2 = SomeMethod_B_ToCallStoredProcedure();;

Line 3. string[] X = await Task.WhenAll(t1,t2);

OR

Line 4. string[] X = Task.WhenAll(t1,t2)
Line 5. await X;

OR

Line 6. string[] X = Task.WhenAll(t1,t2)
Line 7. X.wait;

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,857 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Karen Payne MVP 35,406 Reputation points
    2022-02-20T08:41:04.05+00:00

    The standard pattern is shown below where everything is exposed rather than abstract which provides clarity in regards to there is no guessing to what the results will be.

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Globalization;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace WhenAllConsole
    {
        /// <summary>
        /// - Written with .NET Core 5
        /// - Debug.WriteLine is used rather than Console.WriteLine
        ///   so results are available after closing the app
        /// </summary>
        class Program
        {
            static async Task Main(string[] args)
            {
                Task<List<string>> monthNames = SecondTask();
                Task<bool> nameChange = FirstTask();
                Task<List<PersonItem>> groupedTask = ThirdTask();
    
                await Task.WhenAll(nameChange, monthNames, groupedTask);
                Debug.WriteLine("");
                Debug.WriteLine($"Task 1: {nameChange.Result}");
                Debug.WriteLine($"Task 2: {string.Join(",", monthNames.Result.ToArray())}");
    
                groupedTask.Result.ForEach(personItem => Debug.WriteLine(personItem));
                Debug.WriteLine("");
            }
    
            public static async Task<bool> FirstTask()
            {
                return await Task.Run(async () =>
                {
    
                    await Task.Delay(1000);
    
                    return Environment.UserName == "PayneK";
                });
    
            }
            public static async Task<List<string>> SecondTask()
            {
                return await Task.Run(async () =>
                {
    
                    await Task.Delay(3000);
    
                    return Enumerable.Range(1, 12).Select((index)
                            => DateTimeFormatInfo.CurrentInfo.GetMonthName(index))
                        .ToList(); ;
                });
    
            }
    
            public static async Task<List<PersonItem>> ThirdTask()
            {
                return await Task.Run(async () =>
                {
                    await Task.Delay(1);
                    var results = Data.Mocked().GroupBy(person => person.Customer)
                        .OrderByDescending(group => group.Max(person => person.Total))
                        .Select(group => group.OrderBy(person => person.Total))
                        .Select((people, index) => new { RowIndex = index + 1, item = people }).ToList();
    
                    List<PersonItem> list = new();
                    list.AddRange(from result in results
                        select new PersonItem()
                        {
                            Index = result.RowIndex,
                            Person = result.item.LastOrDefault()
                        });
                    return list;
                });
    
            }
    
    
        }
        public class Data
        {
            public static List<Person> Mocked() => new()
            {
                new() { Id = 1, Customer = "Sally", Total = 1 },
                new() { Id = 2, Customer = "Joe", Total = 2 },
                new() { Id = 3, Customer = "Bill", Total = 5 },
                new() { Id = 4, Customer = "Sally", Total = 3 },
                new() { Id = 5, Customer = "Joe", Total = 6 }
            };
    
        }
    
        public class PersonItem
        {
            public int Index { get; set; }
            public Person Person { get; set; }
            public override string ToString() => $"{Index} - {Person}";
    
        }
        public class Person
        {
            public int Id { get; set; }
            public string Customer { get; set; }
            public int Total { get; set; }
            public override string ToString()
            {
                return $"{Customer},{Total}";
            }
        }
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.