- (법, 규칙 등을 ) 들먹이다. (누구의 이름을) 부르다, (프로그램 등을 )불러오다 라는 뜻을 가지고 있으며, 특히 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 |