53. Task.Run vs Task.Factory.StartNew (언래핑·스케줄러·async 델리게이트 함정)

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 주제: Task.Run vs Task.Factory.StartNew (언래핑·TaskScheduler·async 델리게이트 함정)
//
// 과제:
//   1) RunViaRun 과 RunViaStartNew 는 겉보기엔 같은 일을 하지만, 반환·대기
//      의미가 다르다. StartNew 에 async 람다를 넘겼을 때 반환 타입과
//      "언제 완료로 간주되는가"를 예측하라. WaitAll 이후 outer 작업의 실제
//      진행 상태는?
//   2) Task.Run(async ...) 와 Task.Factory.StartNew(async ...) 의 차이를
//      Unwrap, 기본 TaskScheduler(Current vs Default), 기본 TaskCreationOptions
//      관점에서 설명하라.
//   3) 라이브러리/게임서버 코드에서 StartNew 가 만드는 대표적 버그(자식 작업이
//      끝나기 전에 완료된 것으로 오인, 스레드풀이 아닌 스케줄러에서 실행)를
//      들고, 안전한 대안을 제시하라.

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

public static class JobRunner
{
    static async Task DoWorkAsync()
    {
        await Task.Delay(50);
        Console.WriteLine("work finished");
    }

    public static Task RunViaRun()
    {
        // async 델리게이트
        return Task.Run(async () => await DoWorkAsync());
    }

    public static Task RunViaStartNew()
    {
        // 동일해 보이지만 반환/완료 의미가 다르다
        return Task.Factory.StartNew(async () => await DoWorkAsync());
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.