스토리지

[3.29] ★async 및 await을 이용한 비동기 프로그래밍 1★ 본문

Unity/수업내용(C#)

[3.29] ★async 및 await을 이용한 비동기 프로그래밍 1★

ljw4104 2021. 3. 29. 12:55

비동기

  • 한 번에 하나의 일만 하지않고 여러가지의 일을 하는 것.
  • 동기로 하면 하나의 일이 끝날 때 까지 다른 작업을 할 수 없는 것에 비해 비동기는 작업이 완료되는 것을 기다리는 동안 다른 일을 할 수 있다.

docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/async/

 

C#의 비동기 프로그래밍

async, await 및 Task를 사용하여 비동기 프로그래밍을 지원하는 C# 언어에 대해 간략히 설명합니다.

docs.microsoft.com

 

Task

  • 비동기 작업을 나타내는 키워드이다.
using System;
using System.Threading.Tasks;

public class Example
{
   public static async Task Main()
   {
      await Task.Run( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations

 

async 키워드

  • async 키워드는 단순하게 이 메서드에서 await를 사용한다라고 명시하는 키워드이다.
  • Task<TResult>, Task, void 를 반환타입으로 할 수 있지만 대개 Task<TResult>로 하는 것이 좋다.

 

 

★await 키워드

  • 순차적으로 진행하다가 이 작업을 수행하면서 다른작업을 수행하려고 할 때 이 키워드를 붙이면된다.
  • await 키워드를 붙인 문장부터 다른 기능들을 비동기적으로 수행할 수 있다.

 

EX ) 빵을 토스트기에 구우면서 계란후라이 하기

using System;
using System.Threading.Tasks;

namespace Study00
{
    public class Egg
    {

    }

    public class Toast
    {

    }

    public class App
    {
        public void Run()					//Main에서 호출 후 실행
        {
            var eggsTask = FryEggsAsync(2);     //일을 만든다
            Task<Toast> task = MakeToast(2);    
            eggsTask.Wait();                    //일이 완료될때까지 기다린다.
            task.Wait();

            
            Console.WriteLine(task.Result);
        }

        private async Task<Toast> MakeToast(int num)
        {
            for (int i = 0; i < num; i++)
            {
                Console.WriteLine("토스트기에 빵을 넣었습니다.");
            }
            await Task.Delay(2000);             //2초 대기
            Console.WriteLine("빵이 됐습니다.");
            await Task.Delay(1000);             //1초 대기
            Console.WriteLine("빵을 꺼냈습니다.");

            return new Toast();
        }

        private async Task<Egg> FryEggsAsync(int howMany)
        {
            Console.WriteLine("Warming the egg pan...");
            await Task.Delay(3000);
            Console.WriteLine($"cracking {howMany} eggs");
            Console.WriteLine("cooking the eggs ...");
            await Task.Delay(3000);
            Console.WriteLine("Put eggs on plate");

            return new Egg();
        }
    }
}
  • 동기적으로 실행하면 이 코드상으로 계란후라이 ▶ 토스트빵 굽기 순서로 진행되기에 계란이 익는 동안에는 아무것도 할 수가 없다.
  • FryEggsAsync() 메서드 안에서 후라이팬을 달구는 동안 빵 2개를 토스트기에 넣을 수 있다. 그리고 달궈지는데는 3초가 걸리므로 그동안 빵이 다 된다. 이런 식으로 시간에 따라 서로 다른 동작들을 수행할 수 있다.
  • 이러한 방식으로 비동기적 프로그래밍을 수행할 수 있다.

계란후라이를 하면서 토스트를 굽는다.

보기에는 스레드와 기능이 비슷하다고 할 수 있다.

  • 스레드또한 프로세스의 흐름을 여러개를 두어 여러가지 행동들을 수행할 수 있다.
  • 하지만 스레드로 작성하면 코드가 좀 더러워진다.
  • 또한 우선순위를 마음대로 지정할 수 없다. => 계란후아리와 토스트를 동시에 한들 계란후라이를 먼저할지 토스트를 먼저할 지 우리가 정할 수가 없다.
Comments