2012-04-20 2 views
3

이 링크의 코드에서 http://c-sharp-programming.blogspot.com/2008/07/cross-thread-operation-not-valid.html은 대리자를 사용하여 텍스트 상자의 값을 작업자 스레드에서 업데이트합니다.대리자 호출 구문 설명 C#

기본적으로 내가 무슨 일이 일어나고 있는지 볼 수 있지만, 특히이 라인의 구문 수 있습니다

label1.Invoke(del, new object[] { newText }); 

나에게 혼란이다. 누군가 설명해 주시겠습니까? 매개 변수가 하나 뿐인데 왜 대리자에 새 개체 배열 구문을 사용합니까?

전체 코드 :

delegate void updateLabelTextDelegate(string newText); 
private void updateLabelText(string newText) 
{ 
if (label1.InvokeRequired) 
{ 
    // this is worker thread 
    updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText); 
    label1.Invoke(del, new object[] { newText }); 
} 
else 
{ 
    // this is UI thread 
    label1.Text = newText; 
} 
} 
+0

실수로, label1.Invoke()가 대리자가 아닙니다. 그냥'label1.Invoke (del, newText);라고 쓰십시오. –

+0

그는 label1.Invoke()가 델리게이트라고 말 했나요? 나는 그것을 읽지 않았다. 또한 params 덕분에 명시 적 객체 []가 없어도 하나의 param을 사용할 수 있습니다. – payo

답변

4

TL; DR :

Control.Invoke 모든 델리게이트 타입 작동 파라미터 객체 배열을 대리인 DynamicInvoke에 호출된다.

//

함수 포인터의 유형을 지정하는 것와 똑같이에서 C#의 키워드 delegate. 해당 유형을 사용하여 특정 서명의 메서드를 전달할 수 있습니다. 귀하의 예제에서 서명은 1 arg (문자열)을 취하고 아무것도 반환하지 않는 (void) 메서드에 대한 것입니다. 방법 updateLabelText가 그 시그널과 일치합니다. 라인 :

updateLabelTextDelegate del = updateLabelText; 

그런 다음 지금 Control.Invoke 방법 방법 updateLabelText에 대한 포인터입니다 귀하의 변수 del을 전달할 수 있습니다

updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText); 

는 말의 전체 텍스트 방식입니다. 되는 Control.Invoke 서명에 사용 params 덕분에, 당신도없는

label1.Invoke(del, new object[] { newText }); 

명시 적으로는 object[]

label1.Invoke(del, newText); 

Invoke 그것을 사용할 것이다 객체의 배열을 취의 대답 주어진 대의원에게 의논으로서. 당신의 변수 del으로 (예 귀하의 업데이트 방법은 독서를 유지, 하나 개의 문자열 인수 소요) 당신 전화 updateLabelText 자신 : 본질적으로 같은 것이다

del(newText); 

등 :

updateLabelText(newText); 

Control.Invoke을 내부 , 그들은 당신의 del 메서드를 호출하고 있지만 이 아니기 때문에 델리게이트의 헬퍼 메서드 덕분에 얼마나 많은 arg가 필요한지 알 수 있습니다.

편집 내가 한 어떤 깊은 과학 파고의 invocation이 내부적으로 더 같은 : 당신이 뭔가를 찾아 낼 것입니다 argsobject[]입니다

del.DynamicInvoke(args); 

. 대리자 변수 (대리자 유형)로 수행 할 수있는 작업에 대한 자세한 내용은 here을 참조하십시오.

+0

자세한 답변 해 주셔서 감사합니다. :) –

2

개체 배열이 대리자의 Invoke 메서드에 전달됩니다. 이 경우 updateLabelTextDelegate은 단일 string 매개 변수를 취하므로 배열의 단일 요소입니다.

label1.Invoke(del, newText) 

배열이 명시 적으로 생성 할 필요가 없습니다 사실

도 유효합니다.

+0

+1은'new object []'를 사용하지 않았기 때문에 +1하는 것이'params'의 유일한 옵션이라는 것을 지적 할 것입니다. – payo

1

우선, 위임자가 Invoke을 호출하지 않는다는 점에 유의해야합니다. Invoke컨트롤입니다. 여기에 사용되는 Control.Invoke의 서명 보면 지금, 그것은이있다 :

public Object Invoke(
    Delegate method, 
    params Object[] args 
) 

을하는 방법이 하나의 특정 대리자 형식을했다 경우, 그 위임에 대한 적절한 매개 변수 유형을 걸릴 수 있습니다.

control.Invoke(someDelegate, new object[] { "foo", "bar", 10 }); 

그래서 답이있는 object[]이라고 : 우리가 함께 그렇게 할 수 위의 매우 일반적인 방법을 사용 - 경우 대리인은 하나 개의 매개 변수를 사용하지만, 우리는 Action<string, string, int>를 전달하고 싶었 가정 해 봅시다 대리자 유형도 일반화되어 있기 때문에 일반성을 제공합니다. MethodInfo.Invoke과 약간 비슷합니다. 컴파일 타임에 얼마나 많은 매개 변수가 있는지 모른 채 object[] 유형의 값은 다양한 상황을 허용하는 가장 좋은 방법입니다.

3

Control.Invoke의 메소드 서명을 보면 params Object[] args이 표시됩니다. object[] args 또는 단일 인수를 전달할 수 있습니다.