프로그래밍/C#

[C#] Task.Yield 사용법 및 활용 예제

흔한티벳여우 2024. 9. 3. 12:57
반응형

비동기 프로그래밍은 현대 소프트웨어 개발에서 매우 중요한 역할을 합니다. 특히 UI 응용 프로그램에서는 긴 작업이 UI 스레드를 차단하지 않도록 하여 사용자 경험을 향상시키는 것이 필수적입니다. 이번 포스트에서는 Task.Yield를 사용하여 비동기 작업 중에 UI 응답성을 유지하는 방법에 대해 알아보겠습니다.


Task.Yield란 무엇인가?

Task.Yield는 C#에서 제공하는 비동기 메서드로, 현재 실행 중인 스레드를 일시적으로 양보하고 이후에 다시 제어를 반환받을 수 있게 합니다. 이 메서드는 주로 UI 응용 프로그램이나 비동기 코드에서 긴 작업이 UI 스레드를 차단하지 않도록 하기 위해 사용됩니다.

Task.Yield를 호출하면 await 키워드와 함께 사용되어 현재 실행 중인 작업을 일시적으로 중단하고 다른 대기 중인 작업이 실행될 수 있도록 합니다. 이는 현재 스레드가 다른 작업을 수행할 수 있도록 해줍니다.


Task.Yield 사용 예제

다음은 Task.Yield를 사용하여 비동기 작업 중에 UI 응답성을 유지하는 방법을 보여주는 간단한 예제입니다. 이 예제는 콘솔 응용 프로그램이지만, UI 응용 프로그램과 동일한 원칙이 적용됩니다.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Program started on Thread ID: " + Environment.CurrentManagedThreadId);

        // 긴 작업을 비동기적으로 실행합니다.
        await DoLongRunningTask();

        Console.WriteLine("Program ended on Thread ID: " + Environment.CurrentManagedThreadId);
    }

    static async Task DoLongRunningTask()
    {
        Console.WriteLine("Starting long-running task on Thread ID: " + Environment.CurrentManagedThreadId);

        // 긴 작업을 반복적으로 수행하면서, 각 반복마다 Task.Yield()를 사용하여 UI 스레드를 양보합니다.
        for (int i = 0; i < 5; i++)
        {
            // Task.Yield()를 사용하여 현재 작업을 일시적으로 중단하고, 다른 작업들이 실행될 수 있도록 합니다.
            await Task.Yield();

            // 긴 작업의 일부를 수행합니다. 여기서는 단순히 대기합니다.
            await Task.Delay(1000); // 실제 작업을 나타내기 위해 1초 지연합니다.

            Console.WriteLine($"Iteration {i + 1} completed on Thread ID: " + Environment.CurrentManagedThreadId);
        }

        Console.WriteLine("Long-running task completed on Thread ID: " + Environment.CurrentManagedThreadId);
    }
}

 

예제 설명

  1. Main 메서드:
    • 프로그램의 시작점입니다. DoLongRunningTask 메서드를 호출하여 긴 작업을 비동기적으로 시작합니다.
  2. DoLongRunningTask 메서드
    • 긴 작업을 수행하는 비동기 메서드입니다. 여기서는 for 루프를 사용하여 5번의 반복 작업을 수행합니다.
    • 각 반복마다 Task.Yield()를 호출하여 현재 작업을 일시적으로 중단하고, 다른 대기 중인 작업이 실행될 수 있도록 합니다. 이는 UI 응용 프로그램의 경우 UI 스레드를 주기적으로 양보하여 UI가 응답할 수 있도록 합니다.
    • await Task.Delay(1000)는 1초 동안 지연을 줍니다. 실제로 이 부분은 긴 작업을 시뮬레이션하기 위해 사용됩니다.

실행 결과 예시

Program started on Thread ID: 1
Starting long-running task on Thread ID: 1
Iteration 1 completed on Thread ID: 4
Iteration 2 completed on Thread ID: 4
Iteration 3 completed on Thread ID: 4
Iteration 4 completed on Thread ID: 4
Iteration 5 completed on Thread ID: 4
Long-running task completed on Thread ID: 4
Program ended on Thread ID: 1

결과 해석

  • 프로그램이 시작되면 메인 스레드에서 "Program started on Thread ID: 1"이 출력됩니다.
  • DoLongRunningTask 메서드가 비동기적으로 실행되고, 각 반복마다 Task.Yield()에 의해 현재 실행 중인 스레드를 양보합니다.
  • "Iteration n completed on Thread ID: 4" 출력에서 볼 수 있듯이, 각 작업은 다른 스레드에서 실행될 수 있습니다. 이는 Task.Yield()가 호출되어 컨텍스트 전환이 발생했음을 나타냅니다.
  • 모든 작업이 완료되면 "Program ended on Thread ID: 1"이 출력되어 프로그램이 종료됩니다.

Task.Yield의 활용 시나리오

  1. UI 응용 프로그램에서의 응답성 유지:
    • UI 응용 프로그램에서 긴 시간 동안 실행되는 작업이 UI 스레드를 차단하지 않도록 Task.Yield를 사용하여 UI 스레드의 작업을 주기적으로 양보할 수 있습니다.
  2. 동기 코드에서 비동기 코드로의 전환:
    • 비동기 메서드 내에서 호출되기 전에 일시적으로 컨텍스트를 양보하여, 비동기 작업이 현재 스레드를 차단하지 않도록 보장할 수 있습니다.
  3. 비동기 순차 실행 강제:
    • 특정 코드 블록이 정확히 비동기로 실행되도록 보장할 수 있습니다. 이를 통해 동기적으로 실행될 가능성을 방지하고, 비동기 실행 모델을 강제할 수 있습니다.

마무리

Task.Yield는 비동기 작업에서 현재 스레드를 일시적으로 양보하고, 다른 대기 중인 작업이 실행될 수 있도록 하여 비동기 실행의 효율성과 UI 응용 프로그램의 응답성을 유지하는 데 중요한 역할을 합니다. 사용 시 비동기 코드의 실행 순서를 제어하거나 동기 실행을 피하기 위해 사용될 수 있습니다.

UI 응용 프로그램이나 비동기 작업을 많이 사용하는 프로젝트에서는 Task.Yield를 적절히 활용하여 더 나은 사용자 경험을 제공할 수 있습니다. 이 패턴을 잘 이해하고 활용하여 비동기 프로그래밍의 장점을 최대한 누려보세요!

반응형