2013-02-06 15 views
13

Wcześniej miałemDispatch.Invoke (nowe działanie ...) z parametrem

Dispatcher.Invoke(new Action(() => colorManager.Update())); 

zaktualizować wyświetlacz do WPF z innego wątku. Z powodu projektu musiałem zmienić program i muszę przekazać parametr ColorImageFrame do mojej metody ColorStreamManager.Update().

Po this linku, zmodyfikowałem mój dyspozytora:

Dispatcher.Invoke(new Action<ColorStreamManager, ColorImageFrame>((p,v) => p.Update(v))); 

kompiluje porządku, ale nie będzie działać w ogóle. VS2010 mówi "Niezgodność liczby parametrów." W mojej metodzie ColorStreamManager.Update() mam RaisePropertyChanged(() => Bitmap);

Czy ktoś mógłby wskazać, gdzie popełniłem błąd?

Podpis ColorStreamManager.Update() metody jest następujący:

public void Update(ColorImageFrame frame); 
+2

Jak wygląda deklaracja 'ColorStreamManager.Update'? – Foggzie

+0

Zaktualizowałem moje pytanie, aby odpowiedzieć na twoje pytanie. – ikel

+0

@ikel Nie musimy naprawdę widzieć całej funkcji, tylko podpis metody. – Servy

Odpowiedz

20

Nie chcesz, aby akcja miała parametry, ponieważ Dispatcher nie będzie wiedział, co przekazać tej metodzie. Zamiast tego można zamknąć tę zmienną:

ColorImageFrame someFrame = ...; 
Dispatcher.Invoke(new Action(() => colorManager.Update(someFrame))); 
+0

Ah! _ "zamknij nad zmienną" _ Potrzebowałem tej informacji! – ikel

2

Jeśli zadzwonisz Invoke z Action<T1, T2> delegata, trzeba zdać dwa parametry działania na wezwanie Invoke:

ColorStreamManager colorManager = ... 
ColorImageFrame frame = ... 

Dispatcher.Invoke(
    new Action<ColorStreamManager, ColorImageFrame>((p,v) => p.Update(v)), 
    colorManager, 
    frame); 

Wywołanie Overload, którego używasz, to Dispatcher.Invoke(Delegate, Object[]).

+0

Łatwiej i bardziej syntetycznie jest po prostu zamknąć nad zmiennymi zamiast przekazywać je w ten sposób. – Servy

+0

Ale to nie działa w każdych okolicznościach. Przechwytywanie zmiennych zewnętrznych różni się od jawnego przekazywania ich do Invoke. Zobacz na przykład [tutaj] (http://stackoverflow.com/a/271447/1136211). Ponadto OP wyraźnie prosił o to rozwiązanie. – Clemens

+0

Nie ma tu zastosowania, ponieważ 'Invoke' jest synchroniczny; nie powróci, dopóki delegat nie zostanie uruchomiony i nigdy nie zostanie uruchomiony po powrocie metody. Teraz jeśli używasz 'BeginInvoke', to są potencjalne problemy z semantyką zamknięcia, jeśli nie jesteś ostrożny. Takie problemy można * zawsze * rozwiązać przez proste utworzenie nowej zmiennej lokalnej do przechowywania kopii, w razie potrzeby. Jeśli chodzi o PO, który o to poprosił, OP zażądał, aby uzyskać obiekt, który ma do metody "Aktualizuj", nigdy nie powiedział, że zamknięcia nie można użyć. – Servy