var data = DownloadData(...);
ProcessData(data);

var future = DownloadDataAsync(...);
future.ContinewWith(data => ProcessData(data));

저녁식사 모델링 : 동기 프로그래밍

저녁식사 모델링 : 비동기 프로그래밍(동기 포함)

저녁식사 모델링 : 비동기 프로그래밍

저녁식사 모델링

using System;
using System.Threading;
using System.Threading.Tasks;
namespace Dinner.Common
{
    public class Cooking
    {
        // 동기 방식의 밥 만들기 메서드 
        // <returns>밥</returns>
        public Rice MakeRice()
        {
            Console.WriteLine("밥 생성중...");
            Thread.Sleep(3001);
            return new Rice();
        }
        // 비동기 방식의 밥 만들기 메서드 
        // <returns>밥</returns>
        public async Task<Rice> MakeRiceAsync()
        {
            Console.WriteLine("밥 생성중...");
            await Task.Delay(3001); //[A]
            return new Rice();
        }
        // 동기 방식의 국 만들기 메서드
        // <returns>국</returns>
        public Soup MakeSoup()
        {
            Console.WriteLine("국 생성중...");
            Thread.Sleep(3001);
            return new Soup();
        }
        // 비동기 방식의 국 만들기 메서드
        // <returns>국</returns>
        public async Task<Soup> MakeSoupAsync()
        {
            Console.WriteLine("국 생성중...");
            await Task.Run(() => Task.Delay(3001)); //[B]
            return new Soup();
        }
        // 동기 방식의 달걀 만들기 메서드
        // <returns>달걀</returns>
        public Egg MakeEgg()
        {
            Console.WriteLine("달걀 생성중...");
            Thread.Sleep(3001);
            return new Egg();
        }
        // 비동기 방식의 달걀 만들기 메서드
        // <returns>달걀</returns>
        public async Task<Egg> MakeEggAsync()
        {
            Console.WriteLine("달걀 생성중...");
            await Task.Delay(TimeSpan.FromMilliseconds(3001));
            return await Task.FromResult<Egg>(new Egg()); //[C]
        }
    }
    public class Rice
    {
        // Pass
    }
    public class Soup
    {
        // Pass
    }
    public class Egg
    {
        // Pass
    }
}
using Dinner.Common;
using System;
using System.Diagnostics;
namespace Dinner.Sync
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            //[1] 밥 만들기
            Rice rice = (new Cooking()).MakeRice(); // 스레드 차단: true
            Console.WriteLine($"밥 준비 완료 - {rice.GetHashCode()}");
            //[2] 국 만들기
            Soup soup = (new Cooking()).MakeSoup();
            Console.WriteLine($"국 준비 완료 - {soup.GetHashCode()}");
            //[3] 달걀 만들기
            Egg egg = (new Cooking()).MakeEgg();
            Console.WriteLine($"달걀 준비 완료 - {egg.GetHashCode()}");
            stopwatch.Stop();
            Console.WriteLine($"\n시간: {stopwatch.ElapsedMilliseconds}밀리초");
            Console.WriteLine("동기 방식으로 식사 준비 완료");
        }
    }
}

using Dinner.Common;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Dinner.Async
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            Rice rice = await (new Cooking()).MakeRiceAsync(); // 스레드 차단: false
            Console.WriteLine($"밥 준비 완료: {rice.GetHashCode()}");
            Soup soup = await (new Cooking()).MakeSoupAsync();
            Console.WriteLine($"국 준비 완료: {soup.GetHashCode()}");
            Egg egg = await (new Cooking()).MakeEggAsync();
            Console.WriteLine($"달걀 준비 완료: {egg.GetHashCode()}");
            stopwatch.Stop();
            Console.WriteLine($"\n시간: {stopwatch.ElapsedMilliseconds}밀리초");
            Console.WriteLine("비동기 방식으로 식사 준비 완료");
        }
    }
}

using System;
using static System.Console;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Dinner.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Dinner
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("[?] 어떤 방식으로 실행할까요? (0~4 번호 입력)\n" +
                "0. 동기\t\t1. await\t2. Task<T>\t3. WhenAll\t4. WhenAny ");
            var number = Convert.ToInt32(Console.ReadLine());
            switch (number)
            {
                case 1: // 비동기(동기 프로그램을 포함한)
                    {
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        Egg egg = await (new Cooking()).MakeEggAsync();
                        Console.WriteLine($"달걀 재료 준비 완료: {egg.GetHashCode()}");
                        Rice rice = await (new Cooking()).MakeRiceAsync();
                        Console.WriteLine($"김밥 준비 완료: {rice.GetHashCode()}");
                        Soup soup = await (new Cooking()).MakeSoupAsync();
                        Console.WriteLine($"국 준비 완료: {soup.GetHashCode()}");
                        stopwatch.Stop();
                        Console.WriteLine($"\n시간: {stopwatch.ElapsedMilliseconds}");
                        Console.WriteLine("비동기 방식으로 식사(김밥) 준비 완료");
                    }
                    break;
                case 2: // 비동기(함께 실행)
                    {
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        // 3개의 Async 메서드가 동시 실행
                        Task<Rice> riceTask = (new Cooking()).MakeRiceAsync();
                        Task<Soup> soupTask = (new Cooking()).MakeSoupAsync();
                        Task<Egg> eggTask = (new Cooking()).MakeEggAsync();
                        Rice rice = await riceTask;
                        Console.WriteLine($"식탁에 밥 준비 완료: {rice.GetHashCode()}");
                        Soup soup = await soupTask;
                        Console.WriteLine($"식탁에 국 준비 완료: {soup.GetHashCode()}");
                        Egg egg = await eggTask;
                        Console.WriteLine($"식탁에 달걀 준비 완료: {egg.GetHashCode()}");
                        stopwatch.Stop();
                        Console.WriteLine($"\n시간: {stopwatch.ElapsedMilliseconds}");
                        Console.WriteLine("비동기 방식으로 식사 준비 완료");
                    }
                    break;
                case 3: // 비동기(모두 완료되는 시점)
                    {
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        // 3개의 Async 메서드가 동시 실행
                        Task<Rice> riceTask = (new Cooking()).MakeRiceAsync();
                        Task<Soup> soupTask = (new Cooking()).MakeSoupAsync();
                        Task<Egg> eggTask = (new Cooking()).MakeEggAsync();
                        // 모든 작업이 다 완료될 때까지 대기
                        await Task.WhenAll(riceTask, soupTask, eggTask);
                        Console.WriteLine("식탁에 모든 식사 준비 완료");
                        stopwatch.Stop();
                        Console.WriteLine($"\n시간: {stopwatch.ElapsedMilliseconds}");
                        Console.WriteLine("비동기 방식으로 식사 준비 완료");
                    }
                    break;
                case 4:
                    {
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        // 3개의 Async 메서드가 동시 실행
                        Task<Rice> rTask = (new Cooking()).MakeRiceAsync();
                        Task<Soup> sTask = (new Cooking()).MakeSoupAsync();
                        Task<Egg> eTask = (new Cooking()).MakeEggAsync();
                        // 하나라도 작업이 끝나면 확인
                        var allTasks = new List<Task> { rTask, sTask, eTask };
                        while (allTasks.Any()) // 작업이 하나라도 있으면 실행
                        {
                            Task finished = await Task.WhenAny(allTasks);
                            if (finished == rTask)
                            {
                                Rice rice = await rTask;
                                Console.WriteLine($"밥 준비 완료 - {rice}");
                            }
                            else if (finished == sTask)
                            {
                                Soup soup = await sTask;
                                Console.WriteLine($"국 준비 완료 - {soup}");
                            }
                            else
                            {
                                Egg egg = await eTask;
                                Console.WriteLine($"달걀 준비 완료 - {egg}");
                            }
                            allTasks.Remove(finished); // 끝난 작업은 리스트에서 제거
                        }
                        stopwatch.Stop();
                        Console.WriteLine(
                            $"\n시간: {stopwatch.ElapsedMilliseconds}");
                        Console.WriteLine("비동기 방식으로 식사 준비 완료");
                    }
                    break;
                default: // 동기(Sync)
                    {
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        //[1] 밥 만들기
                        Rice rice = (new Cooking()).MakeRice(); // 스레드 차단: true
                        Console.WriteLine($"밥 준비 완료 - {rice.GetHashCode()}");
                        //[2] 국 만들기
                        Soup soup = (new Cooking()).MakeSoup();
                        Console.WriteLine($"국 준비 완료 - {soup.GetHashCode()}");
                        //[3] 달걀 만들기
                        Egg egg = (new Cooking()).MakeEgg();
                        Console.WriteLine($"달걀 준비 완료 - {egg.GetHashCode()}");
                        stopwatch.Stop();
                        Console.WriteLine($"\n시간: {stopwatch.ElapsedMilliseconds}");
                        Console.WriteLine("동기 방식으로 식사 준비 완료");
                    }
                    break;
            }
        }
    }
}
