Language/C#

[C#] iteration 안에 await문을 넣으면 안되는 이유

범데이 2024. 1. 18. 20:12
728x90

await 키워드를 for 루프 내부에서 사용하면 예상치 못한 동작 또는 오류가 발생할 수 있다. 특히 UI 애플리케이션이나 비동기 코드와 같은 특정 상황에서는 더욱 그렇다. 이는 await 키워드가 비동기 작업이 완료될 때까지 함수의 실행을 일시 중단하는 데 사용되기 때문이다. 부적절하게 사용하면 루프가 의도치 않은 방식으로 작동할 수 있다.

 

 

다음은 잘못된 코드의 예시이다:

async Task ProcessItemsAsync(List<Item> items)
{
    for (int i = 0; i < items.Count; i++)
    {
		...

        // 비동기 작업(예: HTTP 요청)을 대기한다.
        await SomeAsyncMethod();

		...
    }
}

위의 예에서는 루프 내에서 비동기 작업을 대기하면 해당 작업이 완료될 때까지 루프의 실행이 일시 중단된다. 이는 특히 UI Context에서 루프가 UI를 멈출 수 있어 예상치 못한 지연 및 블로킹 동작을 유발할 수 있다.

 

 

루프 내에서 비동기 작업을 처리하려면 일반적으로 여러 비동기 작업을 동시에 시작한 다음 Task.WhenAll과 같은 메커니즘을 사용하여 모든 작업의 완료를 기다리는 것이 좋다.

 

다음은 간단한 예시이다:

async Task ProcessItemsAsync(List<Item> items)
{
    var tasks = new List<Task>();

    for (int i = 0; i < items.Count; i++)
    {
        tasks.Add(ProcessItemAsync(items[i]));
    }

    await Task.WhenAll(tasks);
}

async Task ProcessItemAsync(Item item)
{
	..
    await SomeAsyncMethod();
	..
}

 

이 예시에서는 각 항목의 처리가 별도의 비동기 메서드(ProcessItemAsync) 내에서 캡슐화되고 루프는 이러한 비동기 작업만 시작한다. 그런 다음 루프 내에서 개별 작업을 대기하는 대신 Task.WhenAll을 사용하여 모든 작업의 완료를 기다린다. 이렇게 하면 루프 내에서 개별 작업을 대기하는 대신 모든 작업의 완료를 한 번에 기다릴 수 있다.

 

 

await를 사용하는 방식과 루프의 동작과의 상호 작용을 신중하게 고려하여 의도치 않은 문제를 피해야 한다.

 

 


#References

https://stackoverflow.com/questions/19431494/how-to-use-await-in-a-loop

반응형