[c#] Windows 스토어 앱에서 CoreDispatcher를 가져 오는 올바른 방법

Windows 스토어 앱을 구축 중이며 UI 스레드에 게시해야하는 코드가 있습니다.

이를 위해 CoreDispatcher를 검색하여 코드를 게시하는 데 사용하고 싶습니다.

이를 수행하는 몇 가지 방법이있는 것 같습니다.

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

// Second way
Window.Current.Dispatcher;

어느 것이 맞습니까? 또는 둘 다 동등하다면?



답변

이것이 선호되는 방법입니다.

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

이것이 갖는 장점은 메인을 얻으 CoreApplicationView므로 항상 사용할 수 있다는 것입니다. 자세한 내용은 여기를 참조 하세요 .

사용할 수있는 두 가지 대안이 있습니다.

첫 번째 대안

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

이것은 앱에 대한 활성보기를 가져 오지만 활성화 된보기가없는 경우 null 을 제공합니다 . 자세한 내용은 여기를 참조 하세요 .

두 번째 대안

Window.Current.Dispatcher

이 솔루션은 UI Dispatcher 대신 null 을 반환하므로 다른 스레드에서 호출 될 때 작동하지 않습니다 . 자세한 내용은 여기를 참조 하세요 .


답변

C ++ / CX를 사용하는 모든 사람

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


답변

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


답변

이것은 오래된 스레드이지만 개발자가 저에게 영향을 미치고 대규모 UWP 앱에서 디버깅을 매우 어렵게 만들 수있는 문제에주의를 기울이고 싶었습니다. 필자의 경우 2014 년에 위의 제안에서 다음 코드를 리팩토링했지만 가끔은 본질적으로 무작위로 발생하는 앱 정지로 인해 시달 리곤했습니다.

public static class DispatcherHelper
{
    public static Task RunOnUIThreadAsync(Action action)
    {
        return RunOnUIThreadAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, action);
    }

    public static async Task RunOnUIThreadAsync(Windows.UI.Core.CoreDispatcherPriority priority, Action action)
    {
        try
        {
            await returnDispatcher().RunAsync(priority, () =>
            {
                action();
            });
        }
        catch (Exception ex)
        {
            var noawait = ExceptionHandler.HandleException(ex, false);
        }
    }

    private static Windows.UI.Core.CoreDispatcher returnDispatcher()
    {
        return (Windows.UI.Xaml.Window.Current == null) ?
            CoreApplication.MainView.CoreWindow.Dispatcher :
            CoreApplication.GetCurrentView().CoreWindow.Dispatcher;
    }
}

위에서 나는 정적 클래스를 사용하여 애플리케이션 전체에서 Dispatcher 호출을 허용하여 단일 호출을 허용했습니다. 95 %의 시간 동안 QA 회귀를 통해서도 모든 것이 괜찮 았지만 클라이언트는 때때로 문제를보고했습니다. 해결책은 실제 페이지에서 정적 호출을 사용하지 않고 아래 호출을 포함하는 것이 었습니다.

            await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {

            });

이는 UI 스레드가 App.xaml.cs 또는 스택에 대한 푸시 / 팝을 처리 한 내 Singleton NavigationService에서 호출되었는지 확인해야하는 경우가 아닙니다. 디스패처는 스택에 MessageBus에서 트리거되는 다양한 메시지가있을 때 각 페이지에 자체 UI 스레드가 있기 때문에 어떤 UI 스레드가 호출되었는지 추적하지 못하고있었습니다.

이것이 영향을받을 수있는 다른 사람들에게 도움이되기를 바라며 각 플랫폼이 모범 사례를 다루는 전체 프로젝트를 게시하여 개발자에게 서비스를 제공 할 것이라고 생각합니다.


답변

사실, 나는 이것의 라인에서 무언가를 제안 할 것입니다.

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

이렇게하면 다른보기 / 창을 열면 Dispatcher가 혼동되지 않습니다.

이 작은 보석은 창이 있는지 확인합니다. 없는 경우 MainView의 Dispatcher를 사용하십시오. 보기가 있으면 해당 Dispatcher를 사용하십시오.


답변