In to the C# 2014. 1. 26. 22:40

[C#] Action, Func 그리고 Task

C#의 대리자(delegate)와 Task에 대해서 알아보겠습니다. 대리자와 Task는 항상 따라다니는 기술이며, 수많은 오픈소스도 이 두개의 개념을 적극적으로 사용하여, 비동기 로직을 구현하고 있습니다. Action과 Func은 대리자로 구현되어져 있습니다. Action이 어떻게 구현 되었는지 보겠습니다.

 

정말 별거 없습니다.

잠시만!! Action과 Func의 차이점에 대해서 얘기 하자면, Action은 파라미터만 있는 대리자 역활을 합니다. 즉, 리턴 할 수 없는 대리자 입니다. 반면에 Func은 파라미터 및 리턴 모두 할 수 있는 대리자 입니다. 이 둘의 차이점은 이것 말고는 없습니다.

 

Action은 이런 식으로 16개의 파라미터를 갖을 수 있으며, Func은 16개의 파라미터와 1개의 리턴을 갖을 수 있습니다.

Action과 Func은 굳이 정의할 필요가 없을 듯 보이지만 많은 라이브러리에서 이런 공통적인 대리자를 사용함으로써 사용자의 입장에서 보면 어려움 없이 사용할 수 있도록 하였습니다.

 

간단히 Action 정의 및 사용법에 대해 보겠습니다.

 

Line1을 보면 파라미터 없는 Action을 사용한 것입니다. action이라는 대리자에 익명함수를 정의 한 것입니다.

Line2는 string 파라미터를 갖는 Action입니다. Line3은 string과 int형 파라미터를 갖는 Action 입니다.

Line 5 ~ 7은 함수 사용하듯이 사용합니다.

 

이번엔 Func 입니다.

 

Func은 리턴 값이 꼭 있어야 합니다. 리턴 타입은 가장 마지막에 적어주면 됩니다.

 

이렇듯이 Action과 Func은 함수를 객체처럼 사용할 수 있습니다. 지금까지 Action과 Func을 본 이유는 Task를 설명하기 위해서 입니다.

Task는 C#에서 비동기 작업을 작성하기 위한 코드를 단순화 시켜줍니다. Task는 닷넷프레임워크에서 제공하는 ThreadPool에서 작동합니다. 아쉽지만 Task를 사용할 때는 순서나 시작 시점을 사용자가 지정할 수 없습니다. 즉, Task는 어떠한 비동기 작업을 수행한다라고만 지정해 줄 뿐 수행에 대한 컨트롤을 하기 어렵습니다. 그런데 Task를 왜 쓰냐면 아래와 같습니다.

 

1. 이미 만들어진 Thread에서 작동하기 때문에 Thread를 생성할 필요가 없습니다. Thread생성 비용을 줄일 수 있습니다.

2. 프로그래밍의 복잡도가 낮아집니다. 익명함수를 만들어 Task 실행만 해주면 됩니다.

3. 프로그래밍 복잡도가 낮아지므로써 병행 작업이 가능한 코딩이 쉽습니다.

4. ThreadPool의 모든 Thread가 작업중일 때는 추가 Thread가 생성이 됩니다. 이는 언덕등반오르기 알고리즘을 사용합니다.

 

마이크로소프트에서는 병행프로그래밍을 작성할 때는 가능한 Task를 사용하길 권하고 있습니다. 빠르고 안전하기 때문입니다. 그럼 언제 Thread를 사용하느냐하면,

 

1. 단독 쓰레드에서 안정적으로 지속적인 백그라운드 작업이 필요할 경우 Thread를 생성하여 작업 합니다.

 

굳이 시작시점과 종료시점을 정해야 할 작업이 아니라면 Task를 사용하는 것들 권하는 것입니다. 편하고, 빠르니까요.

 

이 Task는 생성될 때 생성자 파라미터에 Action, Action<object>, Func<TResult>, Func<object, TResult> 형식을 넘길 수 있습니다. 아래와 같이 말이죠.

 

이렇게 Task는 대리자를 통한 익명함수를 넘겨주면서 작업을 비동기 방법으로 수행 할 수 있도록 해줍니다.

Task는 굳이 생성자로 만들고 Start를 해줄 필요는 없습니다. Task는 Factory 메소드가 있어 익명함수를 만들어 넘겨주면 바로 실행 할 수 있도록 해주는 기능도 있습니다.

 

이렇게 하면 Task 생성 및 Start 메소드 호출을 할 필요는 없습니다. 여기까지 Action과 Func 그리고 이들을 사용하는 Task와 Task의 시작에 대해서 알아봤습니다. 다음 포스트에는 Task를 사용하는 방법에 대해서 간단히 알아보겠습니다.

 

'In to the C#' 카테고리의 다른 글

[C#] REST API 만들기  (0) 2014.02.13
[C#] Task의 작업완료  (2) 2014.01.26
[C#] Attribute : 속성  (0) 2014.01.24
Lazy Initialization  (0) 2014.01.20
BookSleeve - Pipelined .NET bindings for redis  (0) 2014.01.17