[ASP.NET Core MVC] 21. async, await 비동기 처리 프로그래밍 구현하기

BruteForceA·2022년 7월 6일
1
post-thumbnail

개발환경

  • Visual Studio Community 2017
  • ASP.NET Core 2.2



쓰레드(thread)란?

쓰레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 하나의 프로세스는 여러개의 쓰레드로 구성이 가능하다. 이러한 실행 방식을 멀티스레드(multithread)라고 한다

  • 하나의 프로세스를 구성하는 쓰레드들은 프로세스에 할당된 메모리, 자원 등을 공유한다.
  • 프로세스와 같이 실행, 준비, 대기 등의 실행 상태를 가지며
    실행 상태가 변할때마다 쓰레드 문맥교환(context switching)을 수행한다.
  • 각 쓰레드별로 자신만의 스택과 레지스터를 가진다.



장점

  • 프로세스보다 생성 및 종료시간, 전환시간이 짧음
  • 프로세스의 메모리, 자원등을 공유하므로 커널의 도움없이 상호간에 통신이 가능



쓰레드와 프로세스 차이

프로세스는 운영체제로부터 자원을 할당받는 작업 단위이고
쓰레드는 프로세스가 할당받은 자원을 이용하는 실행 단위이다.



멀티 스레드? 멀티프로세싱?

멀티 쓰레드

  • 하나의 프로세스에 여러 스레드로 자원을 공유하며 작업을 나누어 수행하는 것이다.

그림참조

그림참조



멀티 프로세스

  • 두개 이상 다수의 프로세서(CPU)가 협력적으로 하나 이상의 작업(Task)을 동시에 처리하는 것이다. (병렬처리)





동기적 프로그래밍

Method1() : 3초
Method2() : 3초
Method3() : 4초

3→3→4 = 총 10초 소요



비동기적 프로그래밍

Method1() : 3초
Method2() : 3초
Method3() : 4초

→3
→3
→4
총 4초 소요
메서드가 각각 독립적으로 동작 해야한다.

그림참조



C# 비동기적 프로그래밍을 위한 키워드

async, await, Task, Task < T>
Task : 쓰레드 안에서 과업의 단위
async 와 await는 쌍으로 적어줘야 한다.



HomeController.cs


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Mvc;
using AsyncAwaitTest.Models;
using System.Threading.Tasks;

namespace AsyncAwaitTest.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {

        // # 테스트 방법  - 전통적인 방식
        Stopwatch watch = new Stopwatch();
            watch.Start();

        // # 새로운 테스트 방식? - > VS Diagonostics Tools
            Test1();
            Test2();
            Test3();
            //watch.Stop();
            //var result = watch.ElapsedMilliseconds;
            return View();
        }

        public async Task<IActionResult> Contact()
        {
            /* await Test1Async();
               await Test2Async();
               await Test3Async(); 
               await 키워드를 만나면 여기서 걸리게 되기 때문에 아래처럼 선언해야한다.*/

            Stopwatch watch = new Stopwatch();
            watch.Start();
            var test1 =  Test1Async();
            var test2 = Test2Async();
            var test3 = Test3Async(); 

            var result1 = await test1; // var result1 = await Test1Async() 처럼 적으면 여기서 걸려버림
            var result2 = await test2;
            var result3 = await test3;
            //var result = watch.ElapsedMilliseconds;
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }

        public int Test1()
        {
            Thread.Sleep(3000);
            return 0;
        }

        public int Test2()
        {
            Thread.Sleep(3000);
            return 0;
        }

        public int Test3()
        {
            Thread.Sleep(4000);
            return 0;
        }

        public async Task<int>  Test1Async()
        {
            await Task.Delay(3000);
            return 0;
        }

        public async Task<int> Test2Async()
        {
            await Task.Delay(3000);
            return 0;

        }

        public async Task<int> Test3Async()
        {
            await Task.Delay(4000);
            return 0;
        }
    }
}



실행화면

동기

비동기



비동기적으로 처리했을때 과연 성능이 좋아질까?

성능상 좋아진 것처럼 보이지만 컴퓨터의 남는 자원을 사용해서 병렬적으로 처리할 수 있는 것들은 처리한 것이고 실제로 성능상 좋아진 게 아니라 응답속도가 빨라진 것이다.




참고

0개의 댓글