본문 바로가기
C#

C#] Asynchronous VS Multithreading

by Fastlane 2023. 4. 25.
728x90
반응형

출처 : https://code-maze.com/csharp-async-vs-multithreading/

 

병렬 프로그래밍의 두가지 주요 기술인 비동기와 멀티스레드에 대해서 알아보자. 

Asynchronous Programming

비동기 프로그래밍은 메인 프로그래밍의 흐름과 독립적으로 statements set이 실행되는 병렬프로그래밍 형태이다. 

프로그램에 blocking operation을 갖고 있을 때, 결과 대기 없이 프로그래밍의 실행을 계속하고 싶을 때 사용한다. 동시에 tasks를 실행할 수 있도록 한다. 

 

C#에서는 async, await 키워드로 비동기 프로그래밍을 할 수 있다. 

Multithreading

thread는 프로그램 내에서 하나의 지속되는 흐름이다. Multithreading은 processor가 동시에 multiple processes를 실행하기 위해 multiple threads를 사용하는 것이다. 

 

C#에서 System.Threadnign namespace가 multithreading을 사용하기 위한 class와 interface를 제공한다. 

Asynchronous Programming vs Multithreading

둘은 다르다. 비동기 프로그래밍은 Tasks의 비동기적 순서이고, Multithreading은 병렬로 실행되는 multiple threads이다. 

Multithreading은 프로그래밍의 비동기적 방법 중 하나이지만, single-thread 비동기 tasks를 가질 수도 있다. 

Async Code Example

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await ExecuteAsyncFunctions();
        }

        public static async Task ExecuteAsyncFunctions()
        {
            var firstAsync = FirstAsync();
            var secondAsync = SecondAsync();
            var thirdAsync = ThirdAsync();
            await Task.WhenAll(firstAsync, secondAsync, thirdAsync);
        }

        public static async Task FirstAsync()
        {
            Console.WriteLine("First Async Method on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(1000);
            Console.WriteLine("First Async Method Continuation on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
        }
        public static async Task SecondAsync()
        {
            Console.WriteLine("Second Async Method on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(1000);
            Console.WriteLine("Second Async Method Continuation on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
        }
        public static async Task ThirdAsync()
        {
            Console.WriteLine("Third Async Method on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
            await Task.Delay(1000);
            Console.WriteLine("Third Async Method Continuation on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
        }
    } 
}
output : 

First Async Method on Thread with Id: 1
Second Async Method on Thread with Id: 1
Third Async Method on Thread with Id: 1
Second Async Method Continuation on Thread with Id: 8
Third Async Method Continuation on Thread with Id: 5
First Async Method Continuation on Thread with Id: 11

모든 operation이 동일한 thread인 1번으로 시작한다. 하지만 이어지는 실행에서는 다른 thread(8, 5, 11)로 되었다. 

FirstAsync에서 awaiting operation을 만나면 thread는 method로부터 자유로워져 thread pool로 돌아간다. operation이 끝나고 method가 계속되어야 하면 thread pool로부터 새로운 thread가 할당된다. SecondAsync, ThirdAsync에도 동일하게 반복된다. 

Multithreading Code Example

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Multithreading multithreading = new Multithreading();
            multithreading.ExecuteMultithreading();
        }
    }
    public class Multithreading
    {
        public void ExecuteMultithreading()
        {
            Thread t1 = new Thread(new ThreadStart(FirstMethod));
            Thread t2 = new Thread(new ThreadStart(SecondMethod));
            Thread t3 = new Thread(new ThreadStart(ThirdMethod));
            t1.Start();
            t2.Start();
            t3.Start();
        }
        public void FirstMethod()
        {
            Console.WriteLine("First Method on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
            Console.WriteLine("First Method Continuation on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
        }
        public void SecondMethod()
        {
            Console.WriteLine("Second Method on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
            Console.WriteLine("Second Method Continuation on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
        }
        public void ThirdMethod()
        {
            Console.WriteLine("Third Method on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(1000);
            Console.WriteLine("Third Method Continuation on Thread with Id: " + Thread.CurrentThread.ManagedThreadId);
        }
    }
}
output:
First Method on Thread with Id: 10
Second Method on Thread with Id: 11
Third Method on Thread with Id: 12
Third Method Continuation on Thread with Id: 12
First Method Continuation on Thread with Id: 10
Second Method Continuation on Thread with Id: 11

multithreaded methods는 각자 다른 threads에서 실행된다. 하지만 async methods와 다르게 sleep 이후에도 동일한 thread가 유지된다. 

Use Cases 

함수들 사이에 blocking operation을 실행하야 하는 경우, 비동기 프로그래밍을 사용해야 한다. 고정된 thread pool이거나, 앱의 수직적 확장이 필요한 경우 사용한다. 

 

독립 tasks를 실행하는 독립 functions가 있을때 multithreading을 사용한다. 브라우저의 multiple tab에서 multiple files을 다운로드 받는 것이 좋은 예이다. 각 다운로드는 각자 thread에서 실행된다. 

 

 

728x90
반응형

'C#' 카테고리의 다른 글

C#] type, System.Type, System.Reflection  (0) 2023.06.19
C#] System.Collections.Immutable  (0) 2023.05.18
C#] 특수문자 (주석, $, @)  (0) 2023.03.21
.NET] DTO vs POCO 차이점  (0) 2023.02.09
C#] System.Security.Cryptography  (0) 2023.01.16

댓글