마소 문서를 보고 정리하려다가.. 안그래도 헷깔리는 개념인데 번역체까지 더해지니까 이해가 잘 안가서 한번 여기저기서 글 모아서 정리해보려고 한다.
내 생각을 정리했기 때문에 틀릴수도(?) 있다.
싱글 스레딩 환경에서는 사실 대리자라는 개념이 별로 중요하지 않을 수 있다. 어떻게 보면 대리자
필요 없이 해당 스레드가 그냥 실행하면 되니까.
그런데, WPF .NET 프로그램에서 UI 스레드를 동작 스레드랑 분리하는 것은 중요하다. 물론 간단한 작업은 UI 스레드를 돌리면서 거기에서 해도 괜찮다. 근데 조금만 무거운 작업을 하게 되면 사용자와의 상호작용에 문제가 생긴다.
우리 입장에서 보면 버튼을 클릭했는데, 아무런 피드백이 없는 것이다. 이것은 UI 스레드에서 어떤 무거운 동작을 했기 때문이다.
때문에 어떤 동작을 할때 보통 스레드를 생성해서 직접 관리하거나, 아니면 스레드 풀을 통해서 스레드를 자동으로 할당하고 돌려놓으면서 작업을 하게 된다. ( 왠만하면 스레드 풀을 쓰는 것이 나은 것 같긴 하다 )
어쨋든 말이 너무 돌았다. 때문에 우리는 멀티스레딩
언어 환경에서는 다른 스레드에서의 메서드를 대리 호출 할 수 있게끔하는 대리자
에 대해서 잘 알아야 한다.
cf. MethodInvoker, Invoke.... 등등...
서론이 너무 길었다.
메서드 시그니쳐라고 하면 보통
이름과 매개변수를 말한다. 그러니까 한번 보면
ExampleFunction ( string param1, .... )
뭐 이런식이고 대리자를 선언하려면
접근한정자 delegate 이름(매개변수);
하면 된다. (delegate 빼고는 메서드선언과 별로 다를 것이 없다 ). 그리고 저건 변수지만 나중에 메서드처럼 호출할 수 있다.
내부적으로 보면, 저걸 갖다가 어떤 메서드랑 연결했다고 하면 그 메서드의 메모리 주소를 넣어주는 것이다. 그렇기 때문에 대리자호출을 하더라도 결국 그 메서드를 실행하는 것과 다를바 없다.
코드를 볼까?
하단은
namespace ForExecute
{
delegate void DelegateFunc(string msg);
internal class Program
{
private static void Main(string[] args)
{
DelegateFunc dl = Program.ExFunc1;
dl += Program.ExFunc2;
dl = new DelegateFunc(Program.ExFunc1) + new DelegateFunc(Program.ExFunc2);
dl("test");
}
static void ExFunc1(string msg)
{
Console.WriteLine("1");
Console.WriteLine(msg);
}
static void ExFunc2(string msg)
{
Console.WriteLine("2");
Console.WriteLine(msg);
}
}
}
이렇게 되면 결과가 어떻게 될까?
1
test
2
test가 출력될 것이다.
이것은 이렇게 활용될 수도 있는데 예를 들어서
static void ExFunc1(string msg)~~~가 있다고 쳐보자. 이걸 메서드 자체를 받아다가 실행하고 싶다. 그러면 어떻게 해야할까
받는 메서드를
void ForExecute(){
// execute
}라고 했을 때 저 매개변수 자리에서 위의 ExFunc1 메서드를 받을 수 있어야 한다.
이 경우에 C#에서 이를 받으려면
delegate void DeleFunc1(string msg); 해서
void ForExecute(DeleFunc1 func1 ~~ )으로 받을 수 있다. 사실 굳이 이렇게 안해도 되는데
void ExFunc1은 Action으로도 받을 수 있다.
Action
Action
Func
Func<string, int>
Func은 어떤 것을 반환하는 함수를 말한다.
그러면 void ForExecute(Action func,) 으로 받을 수 있다.
아이고 복잡해 그런데 이런 대리자 개념이 도대체 어디에 쓰일까.. 바로 이벤트와 관련이 있다.
wpf .net에서 어떤 클릭 이벤트가 있다고 쳐보자. 예를 들어서 StartButtonHandler 가 있다고 쳐보자. 그럼 StartButton을 클릭했을 때 나는 Shout()라는 함수를 실행시키고 싶어
그러면
StartButtonHandler += Shout;
이런식으로 대리자 체인을 시키는 것이다.
내 생각을 정리한 것이라서 틀린 부분이 있을 수 있다. 발견하면 추후에 수정하게따. 그럼 20000