2013-04-10 21 views
5

Szukałem prawie wszędzie w Internecie, a ja googlowałem wiele razy i znalazłem tak wiele wyników, ale wciąż nie mogę znaleźć rozwiązania mojego problemu.Jak prawidłowo używać Dispatcher.BeginInvoke?

Jestem zajęty konwersją starej aplikacji WinForms do nowej aplikacji WPF, ale mam problem z niektórymi poleceniami. W aplikacji WinForm używają one Control.BeginInvoke() i przechowują ją w obiekcie IAsyncResult. Czytałem, że Dispatcher.BeginInvoke()WPF jest równoznaczne z Control.BeginInvoke() dla WinForms ale otrzymuję ten błąd, gdy używam

Dispatcher.BeginInvoke(): „Nie można niejawnie przekonwertować typu «System.Windows.Threading.DispatcherOperation» do "System.IAsyncResult". Konieczna jest jawna konwersja (czy brakuje Ci obsady?) ".

Każda pomoc zostanie doceniona.

Oto kod, który próbuję przekonwertować. To jest oryginalny kod WinForms. Jestem w stanie przekonwertować wszystko z wyjątkiem części BeginInvoke.

Poniżej znajduje się mój kod, który przekonwertowałem do tej pory, w tym część BeginInvoke, z którą walczę.

private void MessageFilter_AddRemove_Invoked(bool addFilter, System.Windows.Forms.IMessageFilter filter) 
    { 
     if (addFilter) 
     { 
      System.Windows.Forms.Application.AddMessageFilter(filter); 
     } 
     else 
     { 
      System.Windows.Forms.Application.RemoveMessageFilter(filter); 
     } 
    } 

    private void MessageFilter_AddRemove(bool addFilter, System.Windows.Forms.IMessageFilter filter) 
    { 
     { 
      IAsyncResult sr = System.Windows.Threading.Dispatcher.BeginInvoke((ESKAN_ADD_REMOVE_MESSAGEFILTER)MessageFilter_AddRemove_Invoked, addFilter, filter); 
      sr.AsyncWaitHandle.WaitOne(2000); 
     } 
    } 

Jeśli wystąpią inne błędy, proszę dać mi znać.

Dzięki

+2

Czy możesz wpisać kod, który próbujesz przekonwertować? Wygląda na to, że używasz zwracanej wartości 'Control.BeginInvoke' w oryginale, ale nie widząc, jak trudno jest skomentować odpowiednią zmianę. –

+0

Odpowiedź Michaela jest dobra - ale warto również zauważyć, że wiersz 'sr.AsyncWaitHandle.WaitOne (2000)' po prostu zatrzymuje bieżący wątek na 2 sekundy, i wydaje się, że jest zbędny (przynajmniej mam nadzieję, że * jest zbędny ...). Jeśli usuniesz ten wiersz, w ogóle nie potrzebujesz wartości zwracanej (tylko wywołanie zwrotne). –

+0

Tak, odpowiedź Michaela jest dobra, ale nadal mam problem z jedną małą częścią. Muszę użyć niestandardowego interfejsu API do wywołania zwrotnego. Jest to część, w której przypisują BeginInvoke() do obiektu IAsyncResult. Próbowałem kilka sposobów, aby uzyskać prawidłowy kod, aby mógł on wykonywać swoją funkcję, ale staram się to naprawić. – GANDA1F

Odpowiedz

4

to dlatego Dispatcher.BeginInvoke, choć może to być odpowiednik operacja logiczna, nie zwraca IAsyncResult, zwraca DispatcherOperation. Spójrz na this blog post, a zobaczysz dobry przykład na to, jak działa Dispatcher. Skopiowałem tutaj odpowiedni przykład kodu, aby upewnić się, że istnieje później.

public Window1() 
{ 
    InitializeComponent(); 

    CheckBox myCheckBox = new CheckBox(); 
    myCheckBox.Content = "A Checkbox"; 

    System.Threading.Thread thread = new System.Threading.Thread(
    new System.Threading.ThreadStart(
     delegate() 
     { 
     System.Windows.Threading.DispatcherOperation 
      dispatcherOp = myCheckBox.Dispatcher.BeginInvoke(
      System.Windows.Threading.DispatcherPriority.Normal, 
      new Action(
      delegate() 
      { 
       myCheckBox.IsChecked = true; 
      } 
     )); 

     dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed); 
     } 
)); 

    thread.Start(); 
} 

void dispatcherOp_Completed(object sender, EventArgs e) 
{ 
    Console.WriteLine("The checkbox has finished being updated!"); 
} 

Zanotuj do tej linii:

dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed); 

to jak będziesz wiedzieć, kiedy jest zakończone - to będzie oddzwoni do ciebie za pośrednictwem tego wydarzenia.

+0

Dziękuję za odpowiedź Michael. Twoje dzieło wielkie dzięki. – GANDA1F

+0

Chciałbym tylko pomóc z jeszcze jedną rzeczą. To znaczy, że muszę przekazać dwie różne zmienne do funkcji, do której dzwonię. Proszę zobaczyć mój kod powyżej, jeśli nie jest jasne. – GANDA1F