반응형
- 메서드에 async(비동기 메서드)와 await(실행 완료까지 대기)가 한 쌍으로 사용함(아주 가끔 await를 안쓰기도 함)
- 비동기 메서드의 반환 값은 Task, Task<T> 형태임
Main 메서드를 비동기로하여 async와 await 키워드 사용
public class AsyncAwaitTest
{
public string Name { get; set; }
public int DelayValue { get; set; }
public AsyncAwaitTest(string name, int delayValue){ Name = name; DelayValue = delayValue; }
public async Task<int> DownloadPageAsync()
{
await StartAsync();
var client = new HttpClient();
byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/en-us/");
await Task.Run(async () =>
{
await Task.Delay(DelayValue);
Console.WriteLine($"{Name}, 다운로드 완료");
});
return content.Length;
}
private async Task StartAsync()
{
await Task.Delay(DelayValue);
Console.WriteLine($"{Name}, 다운로드 시작");
}
}
class Program
{
// Main 메서드를 async 키워드를 붙여 비동기 메서드로 변경
static async Task Main(string[] args)
{
AsyncAwaitTest testA = new AsyncAwaitTest("A", 1000);
AsyncAwaitTest testB = new AsyncAwaitTest("B", 1);
var taskA = await testA.DownloadPageAsync();
var taskB = await testB.DownloadPageAsync();
Console.WriteLine($"테스트 종료, A결과: {taskA}, B결과: {taskB}");
// 비동기 실행중인데 메인이 종료되는 것을 막기 위해
Console.ReadLine();
}
}
동기 메서드에서 Task.Run() 메서드를 사용하여 비동기 메서드 호출
class Program
{
static void Main(string[] args)
{
int taskA = 0;
int taskB = 0;
Task.Run(async () =>
{
AsyncAwaitTest testA = new AsyncAwaitTest("A", 1000);
taskA = await testA.DownloadPageAsync();
Console.WriteLine($"A결과: {taskA}");
AsyncAwaitTest testB = new AsyncAwaitTest("B", 1);
taskB = await testB.DownloadPageAsync();
Console.WriteLine($"B결과: {taskB}");
});
Console.WriteLine($"테스트 종료");
Console.ReadLine();
}
}
class Program
{
static void Main(string[] args)
{
int taskA = 0;
int taskB = 0;
Task.Run(async () =>
{
AsyncAwaitTest testA = new AsyncAwaitTest("A", 1000);
taskA = await testA.DownloadPageAsync();
Console.WriteLine($"A결과: {taskA}");
});
Task.Run(async () =>
{
AsyncAwaitTest testB = new AsyncAwaitTest("B", 1);
taskB = await testB.DownloadPageAsync();
Console.WriteLine($"B결과: {taskB}");
});
Console.WriteLine($"테스트 종료");
Console.ReadLine();
}
}
Task.Delay값을 둘다 1로 줬을 때 결과
AsyncAwaitTest testA = new AsyncAwaitTest("A", 1);
AsyncAwaitTest testB = new AsyncAwaitTest("B", 1);
Task.WhenAll() 메서드 사용하여 모든 작업이 완료될 때까지 대기
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
AsyncAwaitTest testA = new AsyncAwaitTest("A", 1000);
AsyncAwaitTest testB = new AsyncAwaitTest("B", 1000);
AsyncAwaitTest testC = new AsyncAwaitTest("C", 1000);
Task<int> taskA = testA.DownloadPageAsync();
var taskB = testB.DownloadPageAsync();
await Task.WhenAll(taskA, taskB, testC.DownloadPageAsync());
Console.WriteLine("모든 작업 완료");
});
Console.WriteLine($"테스트 종료");
Console.ReadLine();
}
}
Task.WhenAny() 메서드 사용하여 작업 하나씩 완료 확인
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
AsyncAwaitTest testA = new AsyncAwaitTest("A", 1000);
AsyncAwaitTest testB = new AsyncAwaitTest("B", 1000);
AsyncAwaitTest testC = new AsyncAwaitTest("C", 1000);
var taskA = testA.DownloadPageAsync();
var taskB = testB.DownloadPageAsync();
var taskC = testC.DownloadPageAsync();
List<Task> tasks = new List<Task>() { taskA, taskB, taskC };
// 작업이 하나라도 있으면 실행
while (tasks.Any())
{
Task task = await Task.WhenAny(tasks);
if (task == taskA)
{
int i = await taskA;
Console.WriteLine($"A 완료, i: {i}");
}
else if (task == taskB)
{
int i = await taskB;
Console.WriteLine($"B 완료, i: {i}");
}
else if (task == taskC)
{
int i = await taskC;
Console.WriteLine($"C 완료, i: {i}");
}
// 완료된 작업 리스트에서 삭제
tasks.Remove(task);
}
Console.WriteLine("모든 작업 완료");
});
Console.WriteLine($"테스트 종료");
Console.ReadLine();
}
}
반응형
'C#' 카테고리의 다른 글
C# 튜플(Tuple) (0) | 2022.01.02 |
---|---|
C# 리플렉션(reflection) (0) | 2021.12.30 |
C# 확장 메서드 (0) | 2021.12.27 |
C# 이벤트(Event) (0) | 2021.12.26 |
C# 대리자(Delegate), 무명 메서드, 람다식 (0) | 2021.12.26 |