본문 바로가기
프로그래밍/C# .NET

C# Invoke, BeginInvoke

by 개발하는군인 2023. 4. 2.

- (법, 규칙 등을 )  들먹이다. (누구의 이름을) 부르다, (프로그램 등을 )불러오다 라는 뜻을 가지고 있으며, 특히 UI 프로그램에서 Cross Thraed를 방지하기 위해서 Control의 Invoke 또는 BeginInvoke 를 사용한다. 

※ Cross Thread : 해당 특정 Thread가 관리하고 있는 자원을 다른 Thread 가 액세스하였을때 발생한다. 특히 winform의 컨트롤들은 UI Thread 에서 동작하는데,  다른 Thread 가 해당 자원의 속성을 바꾸는 작업을 요청했을때  Cross  Thread 가 발생한다.

 

Invoke 

 

1. Control.Invoke -  UI Thread 에서의 동작을 보장하며, 동기적으로 실행이 끌날 때 까지 대기 한다.

2. Delegate.Invoke - 호출 하는 Thread 와 동일한 Thread 에서의 동작을 보장하며, 동기적으로 실행이 끝날 때 까지 대기한다.

 

이 코드는 위에 코드에서 Control.Invoke를 사용하여  Cross Thread  Exception이 발생하지 않는다.

실제로 각 지점 마다 Thread를 찍어보면, 버튼이 눌렸을때 UI Thread 1번,  Worker Thread 안에서는 2번,  button 컨트롤에서 Invoke로 호출하는 시점에 찍어보면 버튼이 눌렸을때 사용한 UI Thread 1번을 확인 할 수 있다.

 

위와 같은 이유로 만약 button.invoke 내에서 버튼의 속성을 수정하지 않고 worker thread 내 에서 속성을 수정 할 경우 에러가 발생한다.

 

 

BeginInvoke

 

1. Delegate.BeginInvoke : Threadpool 내의 Thread에서 비동기적으로 실행하며,  UI Thread 에서  동작해야 할 경우 안전 하지 않음

2. Control.BeginInvoke : UI Thread 에서의 동작을 보장하며 호출가 동시에 IAsyncResult 객체를 반환하며 비동기적으로 동작함. IAsyncResult  객체를 통해 비동기 작업을 추적 가능

 

이 코드를 실행 시키면  첫번째로 1이 출력  두번째로  3이 출력 세번째로  약 3초 뒤에 1이 출력되고  마지막으로 버튼의 텍스트가 OK로 바뀐다. 출력 결과를 통해 Control.BeginInvoke는  UI Thread 에서 비동기적으로 동작 한다는 것을 확인 할 수 있다.

 

이 코드를 실행하면 첫번째로 1 두번째로  1 이아닌 다른 Thread 값이 출력된다. 출력 결과를 통해  delegate.BeginInvoke는 ThreadPool 에서의 worker thread에서 비동기로 동작하는것을 확인 할 수 있다. 

 

마무리

 

UI Thread 에서 동기 작업이 필요한 경우 Control.Invoke ,  비동기 작업이 필요한 경우는 Control.Begininvoke 를 사용 일반 적인 델리게이트 사용 시 동기적 작업이 필요한 경우 delegate.Invoke  비동기 작업이 필요한 경우delegate.Begininvoke를 사용하면된다.

 

참고로 UI Thread 에서 시간이 오래걸리는 작업을 할 경우 UI 자체가 프리징 걸리니  시간이 오래 걸리는 작업은 Worker Thraed에서 동작 하게하고 실제 속성에 접근 할때만 UI Thread에서 동작하게 구현하자

'프로그래밍 > C# .NET' 카테고리의 다른 글

제네릭 (2)  (0) 2023.04.17
제네릭  (0) 2023.04.16
다양한 로그 수집 하기  (0) 2023.03.27
BCL (1)  (0) 2023.03.25
시작하세요 C# 10 힙  (0) 2023.03.21