async 이름만 봐도 비동기 프로그래밍 같지만
비동기라고 꼭 멀티쓰레드는 아니다.
동기와 다르게 하나가 끝날 때까지 기다리지 않아도 된다는 의미에서 비동기이고,
꼭 멀티쓰레드 환경에서 실행되어야 한다는 보장은 없다.
ex) 한 스레드 안에서 일을 분배해서 함(약간 코루틴 느낌~)
참고로 coroutine은 싱글 스레드에서 동작한다!
Task란?
일감을 만들어서 보내준다~ 대충 이런 의미
using System.Threading.Tasks;
using System;
namespace TaskPractice
{
class Program
{
static Task Test()
{
Console.WriteLine("Task start");
Task t = Task.Delay(3000);
return t;
}
static void Main(string[] args)
{
Task t = Test();
Console.WriteLine("while start");
while (true)
{
}
}
}
}
출력결과
Task start
while start
Task start를 출력하고 바로 while start가 찍힌다.(3초 기다리지 않음)
while start가 출력문이 찍히는 건 3초 기다리는 거와는 별개의 문제다.
만약 기다리게 하고싶다면 아래와 같이 코드를 작성한다.
using System.Threading.Tasks;
using System;
namespace TaskPractice
{
class Program
{
static Task Test()
{
Console.WriteLine("Task start");
Task t = Task.Delay(3000);
return t;
}
static void Main(string[] args)
{
Task t = Test();
// 구간1
t.Wait();
// 구간2
Console.WriteLine("while start");
while (true)
{
}
}
}
}
출력결과
Task start
(3초 뒤)
while start
이를 통해 알 수 있는건,
1. Task의 종료와 상관없이 실행시킬 수 있는 구간1
2. Task가 종료된 뒤 실행시킬 수 있는 구간2
필요에 따라 두 개의 구간을 사용할 수 있다는 것이다.
t.Wait()이 함수 안으로 들어가면 어떻게 될까?
using System.Threading.Tasks;
using System;
namespace TaskPractice
{
class Program
{
static void TestAsync()
{
Console.WriteLine("Task Async start");
Task t = Task.Delay(3000); // 복잡한 작업 (ex. DB나 파일 작업)
t.Wait();
Console.WriteLine("Task Async end");
}
static void Main(string[] args)
{
TestAsync();
Console.WriteLine("while start");
while (true)
{
}
}
}
}
출력결과
Task Async start
(3초 뒤)
Task Async end
while start
하지만 이 코드의 문제는,
오래 걸리는 복잡한 작업(Task.Delay()부분)이 끝날때까지 대기를 해야하기 때문에
외부로 빠져나가지 못해, 다음 부분을 실행하지 못한다.
이것보단 기다리는 동안 다른 작업을 위해 코드 제어권을 넘겨주는 방식이 좋다.
이를 위해서는 await를 쓴다.
using System.Threading.Tasks;
using System;
namespace TaskPractice
{
class Program
{
static async void TestAsync()
{
Console.WriteLine("Task Async start");
Task t = Task.Delay(3000);
await t;
// 위 두 줄을 아래와 같이 한 줄로 쓸 수 있음
// await Task.Delay(3000);
Console.WriteLine("Task Async end");
}
static void Main(string[] args)
{
TestAsync();
Console.WriteLine("while start");
while (true)
{
}
}
}
}
출력 결과
Task Async start
while start
(while start 출력 약 3초 후)
Task Async end
근데 여기서...스레드가 while(true) 무한루프에 빠져있진 않나? 싶은데
Console.WriteLine("Task Async end"); 라인을 디버깅해보면
쓰레드가 나뉘어져서 Task Async end를 출력하는 스레드 / while 무한 루프에 빠져있는 스레드
이렇게 2개로 나뉘어져 있는 걸 확인할 수 있다.
경우에 따라 이렇게 멀티 쓰레드로 잡힐 수도 있다.
Main에 Async Await가 있으면 어떻게 될까?
using System.Threading.Tasks;
using System;
namespace TaskPractice
{
class Program
{
static async Task TestAsync()
{
Console.WriteLine("Task Async start");
await Task.Delay(3000);
Console.WriteLine("Task Async end");
}
static async Task Main(string[] args)
{
await TestAsync();
Console.WriteLine("while start");
while (true)
{
}
}
}
}
출력결과
Task Async start
(3초 뒤)
Task Async end
while start
추가로,
Task<int>와 같이 반환형을 적어 반환값을 return할 수도 있다!
* async await를 쓸 때의 장점(그냥 delay할 때에 비해)
1. 코드 흐름을 넘겨 끝까지 기다리지 않고 다른 일을 할 수 있게 해줌
2. 부분 블럭마다 할 일을 줄 수 있음
ex) await 이전 / await 이후 ... 등
출처
[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part6: 웹 서버 강의 | Rookiss - 인프런
'Unity > Web Server' 카테고리의 다른 글
| [Web Server] HTTP 서버통신 및 API 사용방법 (0) | 2025.10.15 |
|---|---|
| [Web Server] 섹션 3. 고급 C# 문법 - 12. LINQ #2 (0) | 2025.10.09 |
| [Web Server] 섹션 3. 고급 C# 문법 - 12. LINQ #1 (1) | 2025.09.28 |
| [Web Server] 섹션 2. 웹 기초 - 3. 환경 설정 (0) | 2025.08.24 |