출처 : http://blog.danggun.net/2040




wcf가 예전에 사용하던 방식과 달라 이것저것 테스트 하다가 간만에 뜬 에러

 

크로스 스레드 작업이 잘못되었습니다.

아....

 

예전에 WPF에서 한번 소개 하긴 했었습니다만 윈폼에서는 약간다르죠.

(참고 : [WPF] 다른 쓰레드에서 UI쓰레드 접근하기 - Dispatcher.Invoke)

 

 

1. 일반적인 방법

일반적으로 인보크(Invoke)를 사용하려면 델리게이트(Delegate)를 만들어야 합니다.

(참고 : MSDN - Control.Invoke 메서드)

 

일반적인 방법에서는 다음과 같은 순서로 인보크를 사용합니다.

1) 델리게이트 선언

2) 델리게이트에 연결할 함수 생성

3) 델리게이트와 생성한 함수 연결

4) 인보크로 델리게이트 호출

 

 

//1) 델리게이트 선언
/// <summary>
/// 델리게이트 선언(연결 할 함수와 같은 모양이 되도록 만든다.)
/// </summary>
/// <param name="sData"></param>
private delegate void DataDelegate(string sData);

//2) 델리게이트에 연결할 함수 생성
/// <summary>
/// 실제 동작하는 함수(연결 할 함수)
/// </summary>
private void DelegteFuntion(string sData)
{
	label2.Text = sData;
}

//3) 델리게이트와 생성한 함수 연결
//4) 인보크로 델리게이트 호출
//사용할때
this.Invoke(new DataDelegate(DelegteFuntion), "Test!");

 

코드 라인끝

 

이 방법의 가장큰 문제는 원하는 동작만큼 델리게이트를 선언해야 한다는 것입니다-_-;;;;;

그래서 간소화 방법을 사용하죠.

 

 

 

 

 

 

2. 간소화 방법

간소화 방법은 일반적인 방법과는 달리 한줄로  델리게이트를 선언하는 방법 입니다.

메소드인보커 대리자(MethodInvoker Delegate)를 이용하는 방법이죠.

(참고 : MSDN - MethodInvoker 대리자)

 

this.Invoke(new Action(
	delegate()
	{
		label2.Text = "Test";
	}));

//혹은

this.Invoke(new MethodInvoker(
	delegate()
	{
		label2.Text = "Test";
	}));

 

 

깔끔하게 됐죠?

 

메소드인보커를 이용하면 델리게이트를 전역으로 선언하지 않고 사용할수 있습니다.

단 해당 데리자를 따로 저장하지 않으면 1회만 사용할 수 있습니다.

 

 

3. 자신의 쓰래드인지 확인하기

하지만 자신의 쓰래드에서 인보크를 시도하면 에러가 납니다.

이걸 해결하려면 'InvokeRequired'속성을 써야 합니다.

'InvokeRequired'속성은 'System.Windows.Forms'에 속해있는 속성으로 호출된 메소드가 같은 쓰래드인지 아닌지 확인해 줍니다.

if( true == InvokeRequired)
{
	//다른 쓰래드다.
}
else
{
	//같은 쓰래드다.
}

다른 쓰래드일때는 인보크를 해야하고 같은 쓰래드일때는 필요없습니다.

마무리

검색하다가 안 사실이지만 의외로 델리게이트를 간략화 해서 쓰는걸 모르시는 분들이 많으시군요 ㅡ.ㅡ;;;

제 기억으론 책에서도 나왔던거 같은데;;;(아닌가?)

이럴줄 알았으면 빨리 포스팅을 하는 거였는데 ㅡ,.ㅡ;;;

 

 

 


'language > C#' 카테고리의 다른 글

[.Net] 크로스 스레드(Cross Thread) 오류 해결을 위한 인보크(Invoke)  (0) 2017.09.29
전역 후킹  (0) 2014.08.29
Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05