C#

비동기, 동기

윤태영(Coding) 2023. 6. 14. 09:39

< 동기(Synchronous) >

[특징]

a. 한 번에 하나의 작업만 처리한다.
b. 이전 작업이 끝나야 다음 작업이 시작된다.

[일상 예시]

상점에서 손님1이 계산을 하고 있으면, 손님2는 손님1이 계산을 끝내기를 기다려야 한다. 이처럼 한 작업이 끝나야 다음 작업이 시작되는 것을 동기 방식이라고 한다.

 


< 비동기(Asynchronous) >

[특징]
a. 여러 작업을 동시에 처리할 수 있다.
b. 작업들 간에 서로 기다리지 않고 병렬로 진행된다.

[예시]
요리사가 여러 음식을 동시에 준비하는 것과 비슷하다. 비빔면을 조리하는 동안, 짜파게티도 함께 조리할 수 있다.

 

< 장점과 단점 >

동기 :
장점: 코드가 간단하며, 이해하기가 쉽다.
단점: 리소스를 효율적으로 사용하지 못하고, 대기 시간이 길어질 수 있다. (위에서 설명한 것과 같이, 비슷한 예시로 편의점을 생각해봐도 좋다. 계산하시는 분은 원래 한 분이시니, 계산대에 사람이 줄을 서서 기다리고 있는 모습을 상상해보자.)
비동기 :
장점: 리소스를 효율적으로 활용하고, 대기 시간을 줄일 수 있다.
단점: 코드가 복잡해질 수 있고, 디버깅이 어려울 수 있다.

< C# 대표적인 비동기,동기 함수 > 

C#에서 대표적인 비동기 함수는  Async await가 있고 동기 함수는 Sync가 있다.  

비동기 개념중 중요한 개념엔 Task가 있다.

[Async await] :

여러 작업을 동시에 처리할 수 있는 방식.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // 커피 만들기 시작
        var coffeeTask = MakeCoffeeAsync();

        // 사용자 입력 받기
        var userInputTask = GetUserInputAsync();

        // 커피 만들기 작업과 사용자 입력 받기 작업이 모두 완료될 때까지 기다리기.
        await Task.WhenAll(coffeeTask, userInputTask);

        // 커피가 만들어지고 사용자 입력이 완료된 후에 실행되는 코드.
        Console.WriteLine("커피가 준비되었고 사용자 입력이 완료되었습니다.");
    }

    static async Task MakeCoffeeAsync()
    {
        Console.WriteLine("Coffee making process started.");

        // 물을 끓이는 작업
        Console.WriteLine("Boiling water...");
        await Task.Delay(2000); // 2초 동안 대기 (물 끓이는 시간)

        // 커피를 내리는 작업
        Console.WriteLine("Brewing coffee...");
        await Task.Delay(2000); // 2초 동안 대기 (커피 내리는 시간)
    }

    static async Task GetUserInputAsync()
    {
        Console.WriteLine("성함 :"); // 사용자에게 이름을 입력받는 안내 메시지를 출력.
        string name = await Task.Run(() => Console.ReadLine()); // 사용자 입력을 비동기적으로 받아오기.
        Console.WriteLine($"Hello, {name}!"); // 사용자의 이름을 출력.
    }
}

 

 

[Sync]

한 번에 하나의 작업만 처리하는 방식.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Console.WriteLine("Coffee making process started.");
        MakeCoffee();
        Console.WriteLine("Coffee is ready.");
    }

    static void MakeCoffee()
    {
        Console.WriteLine("Boiling water...");
        Thread.Sleep(2000);
        Console.WriteLine("Brewing coffee...");
        Thread.Sleep(2000); 
    }
}

 

[Task] :

async await 구문을 사용할 때 Task를 함께 사용한다.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // 케이크 굽기 시작 (비동기적으로)
        Task bakeCakeTask = BakeCakeAsync();

        // 파스타 만들기 시작 (비동기적으로)
        Task makePastaTask = MakePastaAsync();

        // 샐러드 만들기 시작 (비동기적으로)
        Task makeSaladTask = MakeSaladAsync();

        // 모든 요리가 완료될 때까지 기다림
        await Task.WhenAll(bakeCakeTask, makePastaTask, makeSaladTask);

        Console.WriteLine("모든 요리가 준비되었습니다!");
    }

    static async Task BakeCakeAsync()
    {
        Console.WriteLine("케이크 굽는 중...");
        await Task.Delay(5000); // 케이크 굽는데 5초 걸린다고 가정
        Console.WriteLine("케이크가 완성되었습니다!");
    }

    static async Task MakePastaAsync()
    {
        Console.WriteLine("파스타 만드는 중...");
        await Task.Delay(3000); // 파스타 만드는데 3초 걸린다고 가정
        Console.WriteLine("파스타가 완성되었습니다!");
    }

    static async Task MakeSaladAsync()
    {
        Console.WriteLine("샐러드 만드는 중...");
        await Task.Delay(2000); // 샐러드 만드는데 2초 걸린다고 가정
        Console.WriteLine("샐러드가 완성되었습니다!");
    }
}

요리사가 비빔면을 조리하면서 동시에 짜파게티를 조리하는 코드

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Task cookJjapagettiTask = CookJjapagettiAsync();
        Task cookBibimmyeonTask = CookBibimmyeonAsync();

        await Task.WhenAll(cookJjapagettiTask, cookBibimmyeonTask);

        Console.WriteLine("모든 요리가 완료되었습니다.");
    }

    static async Task CookJjapagettiAsync()
    {
        Console.WriteLine("짜파게티 요리를 시작합니다.");
        await BoilWaterAsync("짜파게티");
        Console.WriteLine("짜파게티 면을 삶습니다.");
        await Task.Delay(2000); // 면을 삶는데 시간이 걸림
        Console.WriteLine("짜파게티를 양념합니다.");
        await Task.Delay(1000); // 양념하는데 시간이 걸림
        Console.WriteLine("짜파게티 요리가 완료되었습니다.");
    }

    static async Task CookBibimmyeonAsync()
    {
        Console.WriteLine("비빔면 요리를 시작합니다.");
        await BoilWaterAsync("비빔면");
        Console.WriteLine("비빔면 면을 삶습니다.");
        await Task.Delay(2000); // 면을 삶는데 시간이 걸림
        Console.WriteLine("비빔면을 양념합니다.");
        await Task.Delay(1000); // 양념하는데 시간이 걸림
        Console.WriteLine("비빔면 요리가 완료되었습니다.");
    }

    static async Task BoilWaterAsync(string dishName)
    {
        Console.WriteLine($"{dishName}을(를) 위해 물을 끓이는 중...");
        await Task.Delay(1000); // 물 끓이는데 시간이 걸림
    }
}

 

 

 

Reference : C#.NET 0.5년차~3년차(파트1)

이 블로그의 모든 내용은 원작자와 출판사로부터 허락을 받아 작성되었습니다.

https://www.inflearn.com/course/lecture?courseSlug=%EB%8B%B7%EB%84%B7-%EC%9C%88%ED%8F%BC-1&unitId=77888&tab=curriculum 

 

학습 페이지

 

www.inflearn.com