내용 보기
작성자
관리자 (IP : 106.247.248.10)
날짜
2023-10-10 13:33
제목
[C#] [스크랩] async 유무에 따른 awaitable 메서드의 병렬 및 예외 처리
|
간단하게 비동기 함수를 다음과 같이 만들고, namespace ConsoleApp1;
internal class Program
{
static async Task Main(string[] args)
{
DateTime now = DateTime.Now;
await DelayAsync(3);
await DelayAsync(6);
Console.WriteLine($"{(DateTime.Now - now).TotalSeconds}"); // 3초 + 6초 대기, 총 9초 소요
}
static async Task DelayAsync(int id)
{
await Task.Delay(id * 1000);
}
}
static async Task Main(string[] args)
{
DateTime now = DateTime.Now;
Task t1 = DelayTask(3); // 3초 작업 시작
Task t2 = DelayAsync(6); // 연이어 6초 작업 시작
await Task.WhenAll(t1, t2); // 6초 소요
Console.WriteLine($"{(DateTime.Now - now).TotalSeconds}");
}
static async Task Main(string[] args)
{
DateTime now = DateTime.Now;
Task t1 = DelayTask(3); // 3초 작업 시작
Task t2 = DelayAsync(6); // 연이어 6초 작업 시작
await t1; // 3초 대기
await t2; // 위의 3초 대기를 포함해 3초 더 대기, 총 6초 소요
Console.WriteLine($"{(DateTime.Now - now).TotalSeconds}");
}
await t2; // 6초 대기 await t1; // 위의 6초 대기 동안에 t1은 이미 종료했으므로 바로 반환
await t1; // t1 작업 대기 후 아래의 코드 실행 await t2;
namespace ConsoleApp1;
internal class Program
{
static async Task Main(string[] args)
{
DateTime now = DateTime.Now;
Task t1 = DelayAsync(3);
Task t2 = DelayAsync(6);
try
{
await t1;
await t2;
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine($"t1.Exception: {t1.Exception}");
Console.WriteLine($"t2.Exception: {t2.Exception}");
}
Console.WriteLine($"{(DateTime.Now - now).TotalSeconds}");
}
static async Task DelayAsync(int id)
{
await Task.Delay(id * 1000);
throw new InvalidOperationException($"{id} - Exception in DelayAsync");
}
}
/* 실행 결과
System.InvalidOperationException: 3 - Exception in DelayAsync
at ConsoleApp1.Program.DelayAsync(Int32 id) in C:\temp\ConsoleApp1\Program.cs:line 71
at ConsoleApp1.Program.Main(String[] args) in C:\temp\ConsoleApp1\Program.cs:line 17
t1.Exception: System.AggregateException: One or more errors occurred. (3 - Exception in DelayAsync)
---> System.InvalidOperationException: 3 - Exception in DelayAsync
at ConsoleApp1.Program.DelayAsync(Int32 id) in C:\temp\ConsoleApp1\Program.cs:line 71
at ConsoleApp1.Program.Main(String[] args) in C:\temp\ConsoleApp1\Program.cs:line 17
--- End of inner exception stack trace ---
t2.Exception:
3.0295292
*/
try
{
await t1;
await t2;
}
catch (Exception e)
{
Console.WriteLine(e);
Console.WriteLine($"t1.Exception: {t1.Exception}");
Console.WriteLine($"t2.Exception: {t2.Exception}"); // 이 시점에는 작업이 진행되지 않아 비어 있지만,
}
Thread.Sleep(3000);
Console.WriteLine($"t2.Exception(2nd): {t2.Exception}"); // 이 시점에는 6초 대기가 끝나 예외 정보가 채워져 있음.
/* 출력 결과
...[생략]...
t2.Exception:
t2.Exception(2nd): System.AggregateException: One or more errors occurred. (6 - Exception in DelayAsync)
---> System.InvalidOperationException: 6 - Exception in DelayAsync
at ConsoleApp1.Program.DelayAsync(Int32 id) in C:\temp\ConsoleApp1\Program.cs:line 71
--- End of inner exception stack trace ---
Task t1 = DelayAsync(3);
Task t2 = DelayAsync(6);
try
{
await Task.WhenAll(t1, t2); // (3초가 아닌) 6초 대기 후,
}
catch (Exception e)
{
Console.WriteLine(t1.Exception);
Console.WriteLine(t2.Exception);
}
/* 출력 결과:
System.AggregateException: One or more errors occurred. (3 - Exception in DelayAsync)
---> System.InvalidOperationException: 3 - Exception in DelayAsync
at ConsoleApp1.Program.DelayAsync(Int32 id) in C:\temp\ConsoleApp1\Program.cs:line 71
at ConsoleApp1.Program.Main(String[] args) in C:\temp\ConsoleApp1\Program.cs:line 50
--- End of inner exception stack trace ---
System.AggregateException: One or more errors occurred. (6 - Exception in DelayAsync)
---> System.InvalidOperationException: 6 - Exception in DelayAsync
at ConsoleApp1.Program.DelayAsync(Int32 id) in C:\temp\ConsoleApp1\Program.cs:line 71
--- End of inner exception stack trace ---
*/
// Task WhenAll의 코드를 직접 구성하는 경우
try
{
Exception? e1 = null, e2 = null;
try
{
await t1;
}
catch (Exception e)
{
e1 = e;
}
try
{
await t2;
}
catch (Exception e)
{
e2 = e;
}
if (e1 != null)
{
throw e1;
}
if (e2 != null)
{
throw e2;
}
}
catch (Exception e)
{
Console.WriteLine($"t1.Exception: {t1.Exception}");
Console.WriteLine($"t2.Exception: {t2.Exception}");
}
C# - 비동기 메서드의 async 예약어 유무에 따른 차이 ; https://www.sysnet.pe.kr/2/0/13421
namespace ConsoleApp1;
internal class Program
{
static async Task Main(string[] args)
{
DateTime now = DateTime.Now;
Task t1 = DelayTask(3);
Task t2 = DelayAsync(6);
try
{
await Task.WhenAll(t1, t2);
}
catch (Exception e)
{
Console.WriteLine(t1.Exception);
Console.WriteLine(t2.Exception);
}
Console.WriteLine($"{(DateTime.Now - now).TotalSeconds}");
}
static Task DelayTask(int id)
{
Task task = Task.Delay(3000);
throw new ApplicationException($"{id} - Exception in DelayTask");
return task;
}
static async Task DelayAsync(int id)
{
await Task.Delay(id * 1000);
throw new InvalidOperationException($"{id} - Exception in DelayAsync");
}
}
/* 출력 결과:
Unhandled exception. System.ApplicationException: 3 - Exception in DelayTask
at ConsoleApp1.Program.DelayTask(Int32 id) in C:\temp\ConsoleApp2\Program.cs:line 31
at ConsoleApp1.Program.Main(String[] args) in C:\temp\ConsoleApp2\Program.cs:line 12
at ConsoleApp1.Program.<Main>(String[] args)
*/
Task t1;
Task t2;
try
{
t1 = DelayTask(3);
t2 = DelayAsync(6);
await Task.WhenAll(t1, t2);
}
catch (Exception e)
{
Console.WriteLine(t1.Exception);
Console.WriteLine(t2.Exception);
}
|
출처1
https://www.sysnet.pe.kr/2/0/13422
출처2