logo MSJO.kr

C# Concurrency with IProgress

2023-08-11
MsJ
 

C#은 동시성(Concurrency) 구현을 쉽게 할 수 있는데 이번 글에서 여러 개의 비동기 함수를 병렬처리 형태로 구현해 보는 예제를 살펴볼 것이다. Concurrency 방식과 Parallel 방식의 비교1는 이전 글인 Concurrency in C# Example 에서 살펴보았다.

아래의 예제처럼 각 1초, 2초, 3초를 소요하는 비동기 방식의 함수가 3개 있다고 가정하고 IProgress 또는 리턴값을 처리한다고 하면 총 6초가량이 걸리게 된다.

async Task Main()
{
    string returnValue1 = await ProgressA(); //1초
    string returnValue2 = await ProgressB(); //2초
    string returnValue3 = await ProgressC(); //3초 : 총 6초
}

위의 예제를 아래처럼 Concurrency를 사용하면 총 3초가 소요되는 병렬처리가 가능하다2.

Concurrency 예제
async Task Main()
{
    Stopwatch sw = new();
    sw.Start();

    Progress<string> progress = new(value =>
    {
        $"Start....................{value}".Dump();
    });

    Progress<int> progressNumber = new(value =>
    {
        $"Start....................{value}".Dump();
    });

    List<Task<string>> tasks = new()
    {
        ProgressA(progress),
        ProgressB(progressNumber),
        ProgressC(progress)
    };

    string[] result = await Task.WhenAll(tasks);

    foreach (string str in result)
    {
        str.Dump();
    }

    sw.Stop();
    ("Stop....." + sw.ElapsedMilliseconds / 1000.0 + "초").Dump();
}

private async Task<string> ProgressA(IProgress<string> progress)
{
    progress.Report("A");
    await Task.Delay(2000);
    return "return A";
}

private async Task<string> ProgressB(IProgress<int> progressNumber)
{
    progressNumber.Report(3);
    await Task.Delay(3000);
    return "return B";
}

private async Task<string> ProgressC(IProgress<string> progress)
{
    progress.Report("C");
    await Task.Delay(1000);
    return "return C";
}
Reference
  1. msjo.kr, “Concurrency in C# Example”
  2. gavilanch3, “Introduction to Asynchronous Programming in C#”

Prεv(Θld)   Nεxt(Nεw)
Content
Search     RSS Feed     BY-NC-ND