2011-02-08 12 views
64

Próbuję zadzwonić pod numer System.Windows.Threading.Dispatcher.BeginInvoke. Sygnatura metody jest następująca:Dispatcher.BeginInvoke: Nie można przekonwertować lambda na System.Delegate

BeginInvoke(Delegate method, params object[] args) 

Próbuję przekazać to Lambda zamiast tworzenia Delegata.

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

Daje mi błąd kompilatora mówiąc, że nie mogę przekonwertować lambda na System.Delegate. Podpis delegata przyjmuje obiekt jako parametr i zwraca nieważne. Moja lambda pasuje do tego, ale nie działa. czego mi brakuje?

Odpowiedz

60

Ponieważ metoda przyjmuje wartość System.Delegate, należy podać jej określony typ uczestnika, który został zadeklarowany jako taki. Można to zrobić poprzez gipsie lub stworzenia określonego delegata poprzez nową DelegateType następująco:

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

Ponadto, jak SLaks Zwraca uwagę, Dispatcher.BeginInvoke bierze tablicę params, więc można po prostu napisać:

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

Lub, jeśli DoSomething to metoda na tej samej obiektu:

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

Jest to 'params' tablicą. – SLaks

+3

Ale nie (x) => {DoSomething(); } pasuje do podpisu delegata? Myślałem, że to wszystko, co powinienem określić. – Micah

+0

@Micah: System.Delegate nie ma podpisu - to po prostu "dowolny delegat" w ogóle. Musisz podać mu typ delegata z sig. który pasuje do twojego użycia. –

59

Shorter:

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

Jeszcze krótszy: Nie sądzę, że potrzebujesz nawiasu klamrowego {} i średnika wokół wyrażenia. – sp3ctum

+3

Nie potrzebujesz nawet(), więc może to być '_dispatcher.BeginInvoke ((Action) (DoSomething));' – mycroes

5

Jeśli odwołujesz się do System.Windows.Presentation.dll z projektu i dodajesz using System.Windows.Threading, możesz uzyskać dostęp do metody rozszerzenia, która pozwala na użycie składni lambda.

using System.Windows.Threading; 

... 

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

Nie mogę tego uruchomić. Czy mógłbyś pójść trochę dalej w szczegóły? –

+0

Dodałem prosty przykład.Pamiętaj, aby odwołać się do System.Windows.Presentation.dll –

+0

To jest dokładnie to, co ja, ale teraz działa ... dziwne. Może ostatnio zrobiłem coś złego. –

5

Korzystanie Inline Lambda ...

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