invoke
invoke는 "호출하다" 라는 뜻으로, 주로 메서드나 델리게이트 ( Delegate )를 실행할 때 사용하는 C# 키워드 / 메서드이다.
invoke 는 델리게이트나 이벤트 , 쓰레드 , UI 컨트롤 등에 연결된 메서드를 실제로 실행 ( call ) 하는 기능을 담당한다.
즉 , "미리 지정된 함수를 실행시킨다" 는 의미로 쓰인다.
C# 에서는 다음과 같은 상황에서 쓰인다
- 델리게이트.Invoke( ) : 델리게이트가 가리키는 메서드 호출
- 컨트롤.Invoke( ) : UI 쓰레드 ( 주 쓰레드 ) 에서 안전하게 메서드를 호출할 때 사용
- 메서드.Invoke( ) : Reflection 으로 메서드를 동적으로 실행할 때 사용
문법
▼델리게이트에서의 Invoke
using System;
delegate void MyDelegate(string message);
class Program
{
static void PrintMessage(string msg)
{
Console.WriteLine(msg);
}
static void Main()
{
MyDelegate del = PrintMessage;
del.Invoke("안녕하세요! Invoke로 호출했습니다."); // Invoke 사용
// del("안녕하세요!") 와 동일
}
}
Invoke( ) 는 델리게이트가 참조하고 있는 메서드를 실행시킨다.
사실상 del( ) 과 같은 의미이지만, 명시적으로 호출할 때 Invoke( ) 를 사용한다.
▼UI 쓰레드에서의 Invoke ( WinForms / WPF )
UI는 메인 쓰레드에서만 접근 가능하므로, 다른 쓰레드에서 UI 변경 시 Invoke( )를 사용해야 한다.
// 예: Form에서 다른 스레드가 UI를 변경하려 할 때
this.Invoke((MethodInvoker)delegate
{
label1.Text = "UI 스레드에서 안전하게 변경됨";
});
this.Invoke( ) 는 UI 컨트롤의 소유 쓰레드 ( 메인 쓰레드 ) 에서 해당 코드를 실행시킨다.
▼Reflection 을 통한 Invoke
using System;
using System.Reflection;
class Program
{
static void Hello() => Console.WriteLine("Hello via Reflection!");
static void Main()
{
MethodInfo method = typeof(Program).GetMethod("Hello", BindingFlags.Static | BindingFlags.NonPublic);
method.Invoke(null, null); // 첫 번째 인자: 인스턴스 (static이면 null)
}
}
컴파일 타임에 메서드 이름을 모를 때 ( 동적 실행 ) Invoke( ) 를 이용한다.
주의할 점
- 델리게이트.Invoke( ) 는 등록된 메서드가 없으면 NullReferenceException 발생
└ 실행 전 ?.Invoke( ) 로 안전하게 호출 가능
del?.Invoke("안전 호출!");
- UI.Invoke( ) 는 해당 컨트롤이 생성된 쓰레드에서만 호출이 가능하다
└ 쓰레드 접근 시 항상 InvokeRequired 로 검사하는 습관을 기르자 - Reflection.Invoke( ) 는 속도가 느리고 디버깅이 어렵다. └ 일반 호출이 가능하면 피하는 게 좋다.
( ) 와 .Invoke( ) 는 동일한가?
결론부터 말하면, "거의 동일하지만 완전히 100% 같지는 않다."
즉, ( ) 와 .Invoke( ) 는 대부분의 상황에서 동일하게 동작하지만 약간의 의미적 기술적 차이가 있다.
myDelegate();
myDelegate.Invoke();
이 두 줄은 똑같이 델리게이트가 참조한 메서드를 실행한다.
▼예시 코드
delegate void PrintDelegate(string msg);
void Print(string msg)
{
Console.WriteLine(msg);
}
PrintDelegate del = Print;
del("안녕!");
del.Invoke("안녕!");
출력 결과는 완전히 같다.
안녕!
안녕!
차이점
| 구분 | ( ) | .Invoke( ) |
| 실행 결과 | 거의 동일 | 거의 동일 |
| 의도 표현 | 단순히 호출한다 | 델리게이트의 Invoke 메서드를 명시적으로 호출한다 |
| 명시성 | 짧고 간단하다 | 명확히 델리게이트의 메서드 실행을 표현한다 |
| Nullable 호출 시 | myDel?.Invoke() 형태만 가능하다 | myDel?.Invoke() 만 안전, myDel?() 는 문법 오류 |
| Reflection 호출 시 | 불가능 | MethodInfo.Invoke() 가능 |
| 확장성 | 단순 함수처럼 보인다 | 오버로드된 Invoke를 명시적으로 호출 가능하다 |
즉 , ?.Invoke( ) 는 델리게이트 호출 시 가장 안전하고 권장되는 방식이다.
( ) 와 .Invoke( ) 는 실행 결과는 같지만, .Invoke( ) 는 델리게이트 호출임을 더 명확히 표현한다.
널 안전 호출 ( ?.Invoke() )이 가능하다는 점에서 조금 더 안전하고 명시적이다.
실무에서는 ?.Invoke() 가 null 체크까지 해주기 때문에 가장 자주 사용한다.
정리
Invoke 는 "대리 실행자 ( Delegate , Control , Reflection ) 를 통해 메서드를 간접적으로 호출하는 기능이다.
즉 , 내가 직접 부르지 않고 누군가를 통해 대신 실행하는 호출자라고 이해하면 된다.
그래도 이해하기 어려우면 "이건 델리게이트 호출이야!!!" 라고 이해하면 된다.
'⭐C Sharp > 12. 델리게이트' 카테고리의 다른 글
| 캡처와 클로저 ( Capture & Closure ) (0) | 2025.11.15 |
|---|---|
| 델리게이트 ( Delegate ) (0) | 2025.09.28 |