69

Buduję aplikację Windows Store i mam kod, który należy opublikować w wątku interfejsu użytkownika.Prawidłowy sposób na zainstalowanie CoreDispatchera w aplikacji Windows Store

W tym celu chciałbym pobrać CoreDispatcher i użyć go do opublikowania kodu.

Wydaje się, że istnieje kilka sposobów, aby to zrobić:

// First way 
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher; 

// Second way 
Window.Current.Dispatcher; 

Zastanawiam się, który z nich jest poprawna? lub jeśli oba są równoważne?

+2

Obie są * rodzaj * poprawne, ale będą miały wartość null, jeśli nie uzyskujesz dostępu do niego z czegoś, co już * ma * dostęp do Dispatchera. Jeśli chcesz go użyć, powiedzmy, ViewModel lub kontroler, musisz przechowywać Dispatchera, ogólnie jako właściwość statyczną w swoim App.xaml.cs lub kontroler IOC, i ustawić ją na pierwszej stronie, która masz ładunek. –

Odpowiedz

113

Jest to preferowany sposób:

Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, 
() => 
{ 
    // Your UI update code goes here! 
}); 

Zaletą tego jest to, że dostaje główną CoreApplicationView i tak jest zawsze dostępny. Więcej szczegółów here.

Istnieją dwie alternatywy, których można użyć.

Pierwsza alternatywa

Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.Dispatcher 

To dostaje aktywnego widoku dla aplikacji, ale to daje NULL, jeśli nie ma poglądy został aktywowany. Więcej szczegółów here.

Druga alternatywa

Window.Current.Dispatcher 

To rozwiązanie nie będzie działać, gdy jest wywołany z innego wątku, ponieważ zwraca NULL zamiast UI Dispatcher. Więcej szczegółów here.

+0

Próbowałem tego, ale kiedy prześledzić kod, kod delegata nadal działa w wątku Worker, a nie "Main Thread". –

+3

Należy pamiętać, że (przynajmniej w Windows 8.1) DispatcherPriority jest teraz CoreDispatcherPriority – Illidan

+0

Zwięzły! Typowa elegancja Microsoft. – devios1

3
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
      CoreDispatcherPriority.Normal, 
      () => { // your code should be here}); 
10

Dla każdego, używając C++/CX

Windows::ApplicationModel::Core::CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
    CoreDispatcherPriority::Normal, 
    ref new Windows::UI::Core::DispatchedHandler([this]() 
{ 
    // do stuff 
})); 
+1

To jest C++/CX, a nie C++. Rozróżnienie jest istotne, ponieważ istnieje wersja Standard C++ dla środowiska wykonawczego Windows: [C++/WinRT] (https://github.com/Microsoft/cppwinrt). – IInspectable

+0

Dobra uwaga - zaktualizowana! –

0

Faktycznie, chciałbym zaproponować coś w linii to:

return (Window.Current == null) ? 
    CoreApplication.MainView.CoreWindow.Dispatcher : 
    CoreApplication.GetCurrentView().CoreWindow.Dispatcher 

ten sposób powinno być openend Another View/Okno, nie dostaniesz zdezorientowanych Dyspozytorów ...

To mały klejnot sprawdza, czy jest nawet okno. Jeśli nie, użyj Dyspozytora MainView. Jeśli jest widok, użyj swojego Dispatchera.

Powiązane problemy