How to use C # async / await / Task (memorial)

3 minute read

Trigger

https://qiita.com/takmot/items/83ca6350b10af959f3db
The following code written in the above article

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
using SignalRChat.Hubs;

namespace SignalRChat
{
    public class app
    {
        private IHubContext<ChatHub> Hub
        {
            get;
            set;
        }
        public app(IHubContext<ChatHub> hub)
        {
            Hub = hub; //Get hub context
        }
        public async Task pushMessage(string msg)
        {
            await Hub.Clients.All.SendAsync("pushMessage", msg); //Send Messege
        }
    }
}

If you don’t add await to the pushMessage call,` you won’t wait for this call, so execution of the current method will continue until the call completes. Consider applying the’await’operator to the result of the call. I get a warning.
I had trouble handling this Task, so I read various articles, but I couldn’t understand it completely.
For the time being, I would like to describe my current understanding and coping.

(Supplement ..)
A warning is issued when calling a method of ʻasync Task. SendAsync didn't warn me when I called it without await. However, if you do not add await, you can not wait for the end of the task like the ʻasync void pattern, it will be thrown and it seems that it is not good.

async / await / Task

Since the above warning appears, add await to Task.
Since it is necessary to add async to the method using await, add async. (Example below method_A ())
If you try to call that method, you will get a warning as well.
Therefore, the caller also adds await / async.
If you use ʻasync void, you don't need await, but it is said that you shouldn't use ʻasync void.

static async Task method_A()
{
    await Task.Run(() => {
        Console.WriteLine($"task contents : {Thread.CurrentThread.ManagedThreadId}");
    });
    Console.WriteLine("method_A Completed");
}
static async Task method_B()
{
    await method_A();
    Console.WriteLine("method_B Completed");
}

The reasons for not using ʻasync void` are as follows.

–You can’t wait with await, so you can’t know the end of the thread, and you’ll be throwing (fire and forget).
–Cannot catch exception

Therefore, we implemented the following.
The comments are the execution order and the thread to be executed.
I am looking at the status of the task after the task is completed with ContinueWith.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace task_sample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"Main start : {Thread.CurrentThread.ManagedThreadId}");                      // 1 (Thread A)
            AsyncMethod().ContinueWith((task) => {
                Console.WriteLine($"task.status {task.Status} : {Thread.CurrentThread.ManagedThreadId}");   // 6 (Thread C)
            });
            Console.WriteLine($"Main end : {Thread.CurrentThread.ManagedThreadId}");                        // 4 (Thread A)

            Console.ReadLine();
        }

        static async Task AsyncMethod()
        {
            Console.WriteLine($"AsyncMethod start : {Thread.CurrentThread.ManagedThreadId}");               // 2 (Thread A)
            await Task.Run(() => {
                Console.WriteLine($"task contents : {Thread.CurrentThread.ManagedThreadId}");               // 3 (Thread B)
            });
            Console.WriteLine($"AsyncMethod end : {Thread.CurrentThread.ManagedThreadId}");                 // 5 (Thread B)
        }
    }
}

You can check the status of the following tasks with task.status.

–TaskStatus.RanToCompletion: Successfully completed
–TaskStatus.Canceled: Canceled
–TaskStatus.Faulted: Exception occurred

If Task has a return value

You can get the return value with task.Result.

using System;
using System.Threading;
using System.Threading.Tasks;

namespace task_sample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"Main start : {Thread.CurrentThread.ManagedThreadId}");                      // 1 (Thread A)
            AsyncMethod().ContinueWith((task) => {
                Console.WriteLine($"task.status {task.Status} : {Thread.CurrentThread.ManagedThreadId}");   // 6 (Thread C)
                Console.WriteLine($"task.Result {task.Result} : {Thread.CurrentThread.ManagedThreadId}");
            });
            Console.WriteLine($"Main end : {Thread.CurrentThread.ManagedThreadId}");                        // 4 (Thread A)

            Console.ReadLine();
        }

        static async Task<string> AsyncMethod()
        {
            Console.WriteLine($"AsyncMethod start : {Thread.CurrentThread.ManagedThreadId}");               // 2 (Thread A)
            await Task.Run(() => {
                Console.WriteLine($"task contents : {Thread.CurrentThread.ManagedThreadId}");               // 3 (Thread B)
            });
            Console.WriteLine($"AsyncMethod end : {Thread.CurrentThread.ManagedThreadId}");                 // 5 (Thread B)

            return "Task Completed";
        }
    }
}

Task.Run()

Task.Run () is
Waiting for reception by some communication → Repeat reception processing
I understand it with the image that I use only when I use an infinite loop.

I made a UDP packet reception task in the following article.
https://qiita.com/takmot/items/6287911115575ab84b05

Reference article

https://qiita.com/acple@github/items/8f63aacb13de9954c5da
https://qiita.com/inew/items/0126270bca99883605de
https://qiita.com/hiki_neet_p/items/d6b3addda6c248e53ef0
https://qiita.com/4_mio_11/items/f9b19c04509328b1e5c1
https://qiita.com/rawr/items/5d49960a4e4d3823722f
http://neue.cc/2013/10/10_429.html
https://stackoverflow.com/questions/62444555/can-i-omit-await-of-clients-all-sendasync-in-net-core-signalr