본문 바로가기
인생은 실전/C#

[C#] Thread - 크로스 스레드(Cross Thread)와 해결 방법 2가지 / InvokeRequired + invoke / CheckForIllegalCrossThreadCalls

by 나는영하 2022. 10. 19.

 Thread - 크로스 스레드 (Cross Thread) 해결 방법 2가지

C#에서 여러개의 Form을 왔다갔다 하면서 다양한 컨트롤을 제어하다보면 심심치 않게 아래와 같은 크로스 스레드 작업 관련 오류 문구를 확인할 수 있다.

 

이는 해당 컨트롤을 관리하는 스레드가 아닌 다른 스레드에서 해당 컨트롤에 접근하게 되면 크로스 스레드 오류가 발생한다고 한다. 

크로스 스레드 오류

 

 

 1. CheckForIllegalCrossThreadCalls

 크로스 스레드 해결 방법으로 첫번째는 

CheckForIllegalCrossThreadCalls의 속성값을 False로 바꾸는 것이다. 

 CheckForIllegalCrossThreadCalls = false;

CheckForIllegalCrossThreadCalls 에 대한 설명

이는 크로스 스레드를 무시하겠다는 설정으로 쓰레드 충돌을 방지하는 것이 아닌 

쓰레드가 충돌하여도 예외 처리를 무시하겠다는 설정이다. 따라서 권장하는 바는 아니다.

 

 2. InvokeRequired + invoke

따라서 권장하는 부분은 아래와 같이 InvokeRequired 속성과 Invoke 매서드를 혼합해서 사용하는 방법이다. 

먼저 InvokeRequired 속성이 True인 경우 해당 컨트롤을 접근하는 스레드가 기존 호출하는 스레드와 다른경우이다.

따라서 Cross Thread가 발생할 수 있는 경우에 해당한다.

InvokeRequired  설명

InvokeRequired를 통해 CrossThread가 발생하는 상황을 분리했다면 Invoke 매서드를 통해 

대리자를 이용해서 메인 스레드에 있는 컨트롤에 접근해서 크로스 스레드의 오류를 방지해준다. 

if (this.InvokeRequired) // 참인경우 Cross Thread가 발생하는 경우
{
	this.Invoke(new Action(delegate ()
	{ 
		//크로스 스레드가 생성되는 코드부                         
	}));
}
else{}

여기서 Invoke 매서드의 인자로 Action을 사용하는 경우와 MethodInvoker를 사용하는 경우 2가지로 나뉜다.

아래의 설명에도 나왔지만 Action은 매개변수를 사용하지 않은 매서드를 실행할 경우 사용되고

(--> Action은 최대 16개의 인자를 가지고 반환값을 가지지 않는 경우)

(--> Func는 최대 16개의 인자를 가지고 반환값도 가지는 경우)

Action은 매개변수가 없는 메서드

 

MethodInvoker는 매개변수를 사용하는 메서드를 실행할 경우 사용되는 듯 싶다.

MethodInvoker는 매개변수를 사용하는 메서드

※ 하지만 인자가 없는 메서드나 함수를 직접 입력했을때 두가지 모두 사용해도 되는 경우가 있다. 그리고 Action은 System에 정의되어 있고 MethodInvoker는 System.Windows.Forms에 정의되어 있는것으로 봤을때 Action이 좀 더 호환성이 좋을 것 같다. 오로지 지극히 개인적인 생각이므로 이부분에 대해선 조금 더 공부해볼 필요가 있다. 

여기서 말하는 매개변수를 사용한다는 거는 반환값이 있다는 얘기라고 생각하면 되는건가?? 인자는 두가지 케이스다 사용하는것으로 알고있는데.. 


Microsoft 문서의 MethodInvoker에 대한 설명

 

이상하게 Microsoft 문서의 MethodInvoker에 대한 설명을 보면 또 다른 설명이 적혀있음을 알 수 있다. (뭐가 맞는 것일까)

 

추가로 Action의 경우 Action <T, T, T, ~> 이런식으로 사용하면 최대 16개 까지의 매개변수를 가지는 메서드를 대리자로 실행 할 수 있다.

최대 16개의 매개 변수를 가지는 메서드를 사용할 수 있다. Action

댓글