question

TZacks-2728 avatar image
0 Votes"
TZacks-2728 asked AgaveJoe commented

C# calling function asynchronously using Task & Await

i have a confusion regarding calling function asynchronously. see a sample code

         private async void button1_Click(object sender, EventArgs e)
     {
         bool retvalue = await SimulateJob();
         Console.WriteLine(retvalue); 
     }

     private Task<bool> SimulateJob()
     {
         bool status = false;

         //await Task.Delay(10000); 
         status = true; 

         return Task.FromResult(status);
     }

1) if i remove async keyword from the function SimulateJob() then function will be treated as synchronous calling function ?
2) a asynchronous function has to have async keyword at the top of function declaration ?
3) is it mandatory to use async keyword if i need to call a function asynchronously ?

4) How many ways i can call a function asynchronously using Task & Await keyword?

please discuss this issue.

Thanks

dotnet-csharp
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AgaveJoe avatar image
1 Vote"
AgaveJoe answered AgaveJoe commented

Take the time to read the openly published documentation which has tons of information. More information than can be pasted into this post...

1) if i remove async keyword from the function SimulateJob() then function will be treated as synchronous calling function ?

The async keyword defines a method as asynchronous. Whether the method contains asynchronous logic or not depends on the method body. Your example method,
SimulateJob(), does not contain asynchronous logic. So there is no reason to defined the method as async.

2) a asynchronous function has to have async keyword at the top of function declaration ?

Yes. A method must be defined as asynchronous to be an asynchronous method. Just like an integer must be declared as "int" to be an integer.

3) is it mandatory to use async keyword if i need to call a function asynchronously ?

I think you misunderstand what asynchronous means which makes answering this question difficult.

The straightforward answer is Yes. Asynchronous methods should be defined with the async keyword if you made a conscious decision to implement the C# async/await pattern (TAP). There are different ways to await multiple tasks, which is covered in the docs, if that's what you are asking.

Keep in mind, async/await is the latest asynchronous programming pattern in C#. There are pervious asynchronous patterns in C# dating back to the early 2000s. Asynchronous is not a new coding concept but TAP newest C# pattern. Learn the pattern if you intend to implement the pattern.

4) How many ways i can call a function asynchronously using Task & Await keyword?

I'm not sure I understand this question. If you defined a method as async and the method invokes async logic then you should use await the async method. Otherwise, the main thread will keep running and the code can/will miss the expected result of the async method. Maybe you are confusing async/await with creating a new thread???

Read the linked docs, it will clear up your confusion.


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Sir please review this code once again

             private async void button1_Click(object sender, EventArgs e)
             {
                 bool retvalue = await SimulateJob();
                 await Task.Delay(10000); 
                 Console.WriteLine(retvalue); 
             }
    
         private async Task<bool> SimulateJob()
         {
             bool status = false;
             await Task.Delay(3000); 
             status = true;
             return status;
         }

you said my SimulateJob() is not asynchronous and after refactor the code now SimulateJob() becomes truly asynchronous ?
or still am i missing something for which one should not consider my SimulateJob() function truly asynchronous ?

if possible please refactor my SimulateJob() function and make it truly asynchronous function. thanks





0 Votes 0 ·
0 Votes 0 ·
karenpayneoregon avatar image
1 Vote"
karenpayneoregon answered karenpayneoregon edited

Here is an example (and yes I'm not working with your code). Code written in .NET Core 5, C#9.

And see the following for best practices.

Classes


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

Tasks


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


Run in button click event


 private async void WhenAllButton_Click(object sender, EventArgs e)
 {
     Task<List<string>> monthNames = SecondTask();
     Task<bool> nameChange = FirstTask();
     Task<List<PersonItem>> groupedTask = ThirdTask();
    
     await Task.WhenAll(nameChange, monthNames, groupedTask);
        
     Debug.WriteLine(nameChange.Result);
     Debug.WriteLine($"{string.Join(",", monthNames.Result.ToArray())}");
        
     groupedTask.Result.ForEach(x => Debug.WriteLine(x));
      
 }


One click results



126095-example.png



example.png (7.8 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.