static Task Test()
{
Console.WriteLine("Start Test");
Task t = TaskDelay(3000);
return t;
}
static void Main(string[] args)
{
Task t = Test();
// t.Wait(); // Wait가 없을경우 비동기로 동작한다.
// 참고로 비동기라고 꼭 멀티쓰레드는 아님(여기선 싱글쓰레드로 동작)
Console.WriteLine("while start");
while(true)
{
}
}
static void TestAsync()
{
Console.WriteLine("Start TestAsync");
Task t = TaskDelay(3000);
t.Wait(); // 여기서 Wait를 해도 될까?
// 여기가 엄청오래 걸리는 함수였다면???
Console.WriteLine("End TestAsync");
}
static void Main(string[] args)
{
TestAsync();
Console.WriteLine("while start");
while(true)
{
}
}
static async void TestAsync()
{
Console.WriteLine("Start TestAsync");
Task t = TaskDelay(3000);
await t; // 대기 하기는 하는데 완료될경우 다음줄이 실행됨.
// 보통은 이렇게 사용함.
// await Task t = TaskDelay(3000);
Console.WriteLine("End TestAsync");
}
static void Main(string[] args)
{
TestAsync();
Console.WriteLine("while start");
while(true)
{
}
}
리턴을 받는것도 가능하다
static async Task<int> TestAsync()
{
Console.WriteLine("Start TestAsync");
await Task t = TaskDelay(3000);
Console.WriteLine("End TestAsync");
return 1;
}
static async Task Main(string[] args)
{
int ret = await TestAsync();
Console.WriteLine("while start");
Console.WriteLine(ret);
while(true)
{
}
}
이런식으로 활용이 가능하다
static async Task Main(string[] args)
{
Task<int> t = TestAsync();
// 다른일을 하다가...
// 필요해지면 대기
int ret = await t;
Console.WriteLine("while start");
Console.WriteLine(ret);
while(true)
{
}
}
Example
using System;
using System.Threading.Tasks;
namespace AsyncBreakfast
{
class Program
{
static void Main(string[] args)
{
// 이렇게 구현할 경우 순차적으로 실행이 된다.
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
Egg eggs = FryEggs(2);
Console.WriteLine("eggs are ready");
Bacon bacon = FryBacon(3);
Console.WriteLine("bacon is ready");
Toast toast = ToastBread(2);
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");
Console.WriteLine("Breakfast is ready!");
}
/* 구현은 생략 */
}
async하게 구현해보자
// ??? 이것도 await만 썼다뿐이지 순차적으로 동작함
// 이렇게 구현하면 안된다.
static async Task Main(string[] args)
{
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
Egg eggs = await FryEggsAsync(2);
Console.WriteLine("eggs are ready");
Bacon bacon = await FryBaconAsync(3);
Console.WriteLine("bacon is ready");
Toast toast = await ToastBreadAsync(2);
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");
Console.WriteLine("Breakfast is ready!");
}
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
// Egg, Bacon, Toast는 비동기로 시작
Task<Egg> eggsTask = FryEggsAsync(2);
Task<Bacon> baconTask = FryBaconAsync(3);
Task<Toast> toastTask = ToastBreadAsync(2);
// 대기는 toast를 먼저대기하고
Toast toast = await toastTask;
ApplyButter(toast);
ApplyJam(toast);
Console.WriteLine("toast is ready");
Juice oj = PourOJ();
Console.WriteLine("oj is ready");
// egg, bacon 순으로 대기
Egg eggs = await eggsTask;
Console.WriteLine("eggs are ready");
Bacon bacon = await baconTask;
Console.WriteLine("bacon is ready");
Console.WriteLine("Breakfast is ready!");
좀 더 개선해보자
static async Task Main(string[] args)
{
Coffee cup = PourCoffee();
Console.WriteLine("coffee is ready");
var eggsTask = FryEggsAsync(2);
var baconTask = FryBaconAsync(3);
var toastTask = MakeToastWithButterAndJamAsync(2);
var breakfastTasks = new List<Task> { eggsTask, baconTask, toastTask };
while (breakfastTasks.Count > 0)
{
Task finishedTask = await Task.WhenAny(breakfastTasks);
if (finishedTask == eggsTask)
{
Console.WriteLine("eggs are ready");
}
else if (finishedTask == baconTask)
{
Console.WriteLine("bacon is ready");
}
else if (finishedTask == toastTask)
{
Console.WriteLine("toast is ready");
}
breakfastTasks.Remove(finishedTask);
}
Juice oj = PourOJ();
Console.WriteLine("oj is ready");
Console.WriteLine("Breakfast is ready!");
}