logo MSJO.kr

Async Await, ContinueWith in C#

2020-09-01
MsJ
 

‘Async Void’ 사용은 일반적으로 아래의 이유를 들어 좋지 않은 것으로 간주한다1.

  • You can’t wait for its completion (fire and forget)
  • Any unhandled exceptions will terminate your process (can’t be caught)
  • Difficult to test

C#에서 악명 높은 ‘Async Void’를 방지하는 좋은 방법으로 ‘ContinueWith’를 사용하는 것인데 아래의 소스는 SingletonSean(유튜브채널)의 ‘C# ASYNC/AWAIT’2 강좌에서 필요한 부분만 추출하여 전체 소스 형태로 편집한 것이다.

Program.cs
using System;
using System.Threading.Tasks;

namespace AsyncAwaitDemo
{
    internal class Program
    {
        private static void Main()
        {
            var car = Car.CreateCarWithStartedEngine(OnEngineStarted);

            Console.WriteLine(car.Status);
            Console.ReadKey(true);
        }

        private static void OnEngineStarted(Task task)
        {
            if (task.Exception != null)
            {
                Console.WriteLine("Failed to start engine");
            }
            else
            {
                Console.WriteLine("Car.IsEngineStarted=" + Car.IsEngineStarted + ", Done.");
            }
        }
    }
}
Car.cs (Model)
using System;
using System.Threading.Tasks;

namespace AsyncAwaitDemo
{
    public class Car
    {
        public static bool IsEngineStarted { get; private set; }

        private Car()
        {
            IsEngineStarted = false;
        }

        public static async Task<Car> CreateCarWithStartedEngine(Action<Task> onEngineStarted)
        {
            var car = new Car();

            await StartEngine().ContinueWith(t => onEngineStarted?.Invoke(t));

            return car;
        }

        private static async Task StartEngine()
        {
            Console.WriteLine("Starting engine.....");
            for (var i = 0; i < 20; i++)
            {
                await Task.Delay(100);
                Console.Write(".");
            }

            Console.WriteLine("");
            await Task.Delay(100);
            IsEngineStarted = true;

            Console.WriteLine("Engine started!");
        }
    }
}
Reference
  1. Brian Lagunas, Why is async void bad and how do I await a Task in an object constructor in C#?

  2. SingletonSean, ContinueWith: Solving async void (response to Brian Lagunas) - C# ASYNC/AWAIT


Prεv(Θld)   Nεxt(Nεw)
Content
Search     RSS Feed     BY-NC-ND