Programming/C# & Unity

C# 비동기 루프 및 실행

장형이 2019. 12. 12. 15:05

개요

.Net C#에서 지원해주는 *Awesome* 한 비동기 기능에 대해서 간단히 기록하려고 게시글을 작성합니다.

정확히는 Parallel 클래스에 관련된 함수들을 소개합니다.

 

Parallel 클래스

간단하게 비동기 작업을 수행할 수 있도록 도와주는 클래스입니다.
Task나 Action, Thread 같은 것들을 직접적으로 만들 필요 없이 기존에 사용하던 Loop나 함수처럼 간단히 사용할 수 있습니다!!

 

Parallel.For (비동기 루프)

루프를 여러 스레드로 나누어 수행하도록 합니다.

// iToPage까지의 게시글 내용을 하나하나 긁어오는 함수.
List<BoardContent> GetBoardContents( int iToPage_ )
{
	List<BoardContent> lstResult = new List<BoardContent>();
	for ( int iPageNumber = 1; iPageNumber <= iToPage_; ++iPageNumber )
	{
		// 해당 게시판 페이지의 내용을 긁어오는 함수. 오래걸린다고 가정.
		lstResult.Add( GetBoardContent( iPageNumber ) );
	}

	return lstResult;
}

// 비동기적으로 게시글 내용을 한번에 긁어오는 함수.
List<BoardContent> GetBoardContents_Parallel( int iToPage_ )
{
	ConcurrentBag<BoardContent> bagContent = new ConcurrentBag<BoardContent>();

	// 0부터 iToPage_까지를 병렬적으로 수행!
	// "bagContent.Add( GetBoardContent( iPageNumber ) )"가 동시에 수행된다.
	Parallel.For( 0,
		iToPage_,
		( iPageNumber ) =>
			bagContent.Add( GetBoardContent( iPageNumber ) )
		);

	return bagContent.ToList();
}

 

 

추가적으로 스레드 수를 제한하고 싶으면 아래와 같이 제한할 수 있습니다.

Parallel.For( 0,
	10,
	new ParallelOptions { MaxDegreeOfParallelism = 4 }, // 4개의 쓰레드로 제한합니다.
	( i ) =>
	{
		Console.WriteLine( i.ToString() );
		Thread.Sleep( 1000 );
	}
	);

Parallel.ForEach (비동기 ForEach)

Paraller.For의 ForEach 버전으로 사용법의 거의 유사합니다.

// 무식하게 하나하나 다운로드 하는 함수.
void Download( List<CDownloader> lstDownloader_ )
{
	foreach( var i in lstDownloader_ )
	{
		i.Download();
	}
}

// 스마ㅡ트하게 한번에 여러개 다운로드 하는 함수.
void ParallelDownload( List<CDownloader> lstDownloader_ )
{
	Parallel.ForEach(
		lstDownloader_,
		( downloader ) => downloader.Download()
		);
}

 

 

Parallel.Invoke (비동기 호출)

원하는 함수를 비동기적으로 동시 호출시키는 함수입니다.

CDownloader downloader1 = new CDownloader();
CDownloader downloader2 = new CDownloader();

// 두 함수를 동시에 실행시킨 다음, 기다린다.
Parallel.Invoke(
	downloader1.Download,
	downloader2.Download
	);

 

정리

쓰는 방법이 매우 쉬운데 효과는 엄청나서 필요할 때 잘 쓰면 좋을 것 같습니다.