Dispatcher.BeginInvoke : 람다를 System.Delegate로 변환 할 수 없습니다.


82

전화하려고 해요 System.Windows.Threading.Dispatcher.BeginInvoke. 메서드의 서명은 다음과 같습니다.

BeginInvoke(Delegate method, params object[] args)

대리인을 생성하는 대신 Lambda를 전달하려고합니다.

_dispatcher.BeginInvoke((sender) => { DoSomething(); }, new object[] { this } );

그것은 나에게 컴파일러 오류를 준다.

람다를 System.Delegate로 변환 할 수 없습니다.

대리자의 서명은 개체를 매개 변수로 사용하고 void를 반환합니다. 내 람다는 이것과 일치하지만 작동하지 않습니다. 내가 무엇을 놓치고 있습니까?

답변:


71

이 메서드는 System.Delegate 를 사용하므로 선언 된 특정 유형의 대리자를 제공해야합니다. 이는 다음과 같이 새 DelegateType을 통해 지정된 델리게이트를 생성하거나 캐스트를 통해 수행 할 수 있습니다.

_dispatcher.BeginInvoke(
     new Action<MyClass>((sender) => { DoSomething(); }),
     new object[] { this } 
  );

또한 SLaks가 지적했듯이 Dispatcher.BeginInvoke 는 params 배열을 사용하므로 다음과 같이 작성할 수 있습니다.

_dispatcher.BeginInvoke(
     new Action<MyClass>((sender) => { DoSomething(); }),
     this
  );

또는 DoSomething이이 개체 자체에 대한 메서드 인 경우 :

_dispatcher.BeginInvoke(new Action(this.DoSomething));

3
하지만 (x) => {DoSomething (); } 대리인의 서명과 일치합니까? 그게 내가 지정해야 할 전부라고 생각했습니다.
Micah

@Micah : System.Delegate에는 서명이 없습니다. "모든 대리인"일뿐입니다. sig와 함께 대리자 유형을 제공해야합니다. 귀하의 사용량과 일치합니다.
Reed Copsey

@Reed 그러나 MyMethod (Action action) 대신 Action이 델리게이트 인 경우 MyMethod (() => {DoSomething ();}); BeginInvoke에 대해 동일한 작업을 수행 할 수없는 이유는 무엇입니까?
Micah

15
@Micah : 실제로 대리인에 대한 서명 이 없기 때문에 문제가 발생합니다. Invoke그리고 BeginInvoke일반적인 가지고 Delegate있는 서명하는 방법을 나타낼 수있는 개체를. 일반적인 상황 (대리자가 특정 서명에 대해 강력한 형식이 지정되는 경우)에서 컴파일러는 특정 대리자 형식을 유추 할 수 있습니다. 이것이 다른 시나리오에서 대리자 유형을 생략 할 수있는 이유입니다. 그러나 여기에는 실제 대리자 형식 없기 때문에 컴파일러에는 대리자 형식을 선택하는 데 사용할 합리적인 근거 (또는 실제로는 수단 )가 없습니다.
Adam Robinson

2
@Micah : BeginInvoke는 BeginInvoke (Action ..)로 선언되지 않고 오히려 BeginInvoke (System.Delegate, ..)로 선언되기 때문에 모든 대리자 유형을 사용할 수 있지만 명시 적으로 지정해야합니다.
Reed Copsey

73

짧게 :

_dispatcher.BeginInvoke((Action)(() => DoSomething()));

8
더 짧게 : 식 주위에 중괄호 {}와 세미콜론이 필요하지 않다고 생각합니다.
sp3ctum 2013 년

3
당신은 ()도 필요하지 않습니다. 그래서 그것은 될 수 있습니다_dispatcher.BeginInvoke((Action)(DoSomething));
mycroes

9

인라인 Lambda 사용 ...

Dispatcher.BeginInvoke((Action)(()=>{
  //Write Code Here
}));

7

프로젝트에서 System.Windows.Presentation.dll을 참조하고 추가 using System.Windows.Threading하면 람다 구문을 사용할 수있는 확장 메서드에 액세스 할 수 있습니다.

using System.Windows.Threading;

...

Dispatcher.BeginInvoke(() =>
{
});

나는 이것을 작동시킬 수 없습니다. 좀 더 자세히 설명해 주시겠습니까?
Tim Pohlmann

간단한 예를 추가했습니다. System.Windows.Presentation.dll
logicnet.dk

그게 바로 나지만 이제는 작동합니다 ... 이상합니다. 지난번에 뭔가 잘못했을 수도 있습니다.
팀 Pohlmann

3

이를 위해 확장 메서드를 만듭니다. 예

public static void BeginInvoke(this Control control, Action action)
    => control.BeginInvoke(action);

이제 형식 내에서 호출 할 수 있습니다 this.BeginInvoke(() => { ... })..

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.