VisualStudio/C#

[C#] Task async awiat

usingsystem 2022. 8. 10. 15:46
728x90

Task와 Thread의 차이점

  • Thread는 병렬 처리를 위해 사용되며, 직접 생성할 경우 시스템 리소스를 많이 소모합니다.
  • ThreadPool을 통해 쓰레드 재사용과 제한을 설정할 수 있지만, 쓰레드 상태를 직접 제어하거나 결과를 반환받는 것이 불편합니다.
  • Task는 ThreadPool 기반으로 동작하며, 쓰레드 생성이 간단하고 결과 값을 반환받는 기능이 포함되어 있습니다.

Task 기본 사용법

ThreadPool 설정에 따라 제한된 쓰레드로 동작하며, 각 Task가 독립적으로 결과를 반환합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace TaskExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. ThreadPool의 쓰레드 수를 제한
            ThreadPool.SetMinThreads(1, 0); // 최소 쓰레드 수 설정
            ThreadPool.SetMaxThreads(2, 0); // 최대 쓰레드 수 설정

            // 2. Task를 저장할 리스트 생성
            var tasks = new List<Task<int>>();

            // 3. 작업 함수 정의 (람다식 사용)
            Func<object, int> work = (param) =>
            {
                var name = (string)param; // 전달받은 파라미터
                int sum = 0;

                // 10번 반복하며 작업 수행
                for (int i = 0; i < 10; i++)
                {
                    sum += i; // 값 누적
                    Console.WriteLine($"{name}: {i}"); // 현재 진행상황 출력
                    Thread.Sleep(200); // 작업 딜레이
                }

                Console.WriteLine($"{name} 작업 완료! 합계: {sum}");
                return sum; // 결과 반환
            };

            // 4. Task 생성 및 리스트에 추가
            tasks.Add(new Task<int>(work, "작업 A"));
            tasks.Add(new Task<int>(work, "작업 B"));

            // 5. Task 시작
            tasks.ForEach(task => task.Start());

            // 6. 모든 Task 완료 대기
            Task.WaitAll(tasks.ToArray());

            // 7. 결과 출력
            Console.WriteLine($"최종 합계: {tasks.Sum(task => task.Result)}");
        }
    }
}

async와 await의 활용

async 키워드는 메서드에 비동기 작업이 포함되어 있음을 나타냅니다. await는 비동기 작업이 완료될 때까지 대기하도록 설정합니다.

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

namespace AsyncAwaitExample
{
    class Program
    {
        // 비동기 작업을 수행하는 메서드
        private static async Task<int> PerformTaskAsync(string name, int delay)
        {
            int sum = 0;

            // Task를 생성하고 실행
            var task = Task.Run(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    sum += i; // 값 누적
                    Console.WriteLine($"{name}: {i}"); // 현재 진행상황 출력
                    Thread.Sleep(delay); // 딜레이 추가
                }

                Console.WriteLine($"{name} 작업 완료! 합계: {sum}");
                return sum;
            });

            // Task가 끝날 때까지 대기
            return await task;
        }

        static async Task Main(string[] args)
        {
            // 비동기 작업 실행
            var result1 = PerformTaskAsync("작업 A", 200);
            var result2 = PerformTaskAsync("작업 B", 100);

            // 결과를 기다린 후 합산
            var totalSum = await result1 + await result2;

            // 결과 출력
            Console.WriteLine($"최종 합계: {totalSum}");
        }
    }
}

async와 ContinueWith 활용

ContinueWith를 사용하면 Task 작업이 끝난 후 추가 작업을 연결할 수 있습니다.

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

namespace ContinueWithExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // 1. 첫 번째 작업 생성
            var firstTask = Task.Run(() =>
            {
                int sum = 0;

                // 0부터 9까지 합산
                for (int i = 0; i < 10; i++)
                {
                    sum += i;
                    Console.WriteLine($"작업 A: {i}");
                    Thread.Sleep(100);
                }

                Console.WriteLine($"작업 A 완료! 합계: {sum}");
                return sum;
            });

            // 2. 첫 번째 작업 완료 후 두 번째 작업 연결
            var secondTask = firstTask.ContinueWith(prevTask =>
            {
                int previousSum = prevTask.Result; // 이전 작업 결과
                int additionalSum = 0;

                // 10부터 19까지 합산
                for (int i = 10; i < 20; i++)
                {
                    additionalSum += i;
                    Console.WriteLine($"작업 B: {i}");
                    Thread.Sleep(100);
                }

                int totalSum = previousSum + additionalSum;
                Console.WriteLine($"작업 B 완료! 최종 합계: {totalSum}");
                return totalSum;
            });

            // 3. 모든 작업 완료 대기
            secondTask.Wait();

            // 4. 최종 결과 출력
            Console.WriteLine($"최종 결과: {secondTask.Result}");
        }
    }
}
728x90