비동기, 동기
< 동기(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)
이 블로그의 모든 내용은 원작자와 출판사로부터 허락을 받아 작성되었습니다.