簡體   English   中英

在 Windows Store 應用程序中獲取 CoreDispatcher 的正確方法

[英]Correct way to get the CoreDispatcher in a Windows Store app

我正在構建一個 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

當它從另一個線程調用時,此解決方案將不起作用,因為它返回null而不是UI Dispatcher 更多細節在這里

對於任何使用 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, () =>
            { 

            });

當我需要確保從 App.xaml.cs 或處理推送/彈出堆棧的 Singleton NavigationService 調用 UI 線程時,情況並非如此。 調度程序顯然正在忘記調用哪個 UI 線程,因為當堆棧具有從 MessageBus 觸發的各種消息時,每個頁面都有自己的 UI 線程。

希望這能幫助其他可能受到影響的人,我認為這也是我認為每個平台都會通過發布涵蓋最佳實踐的完整項目來為其開發人員提供服務的地方。

實際上,我會提出以下建議:

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

這樣,如果你打開另一個視圖/窗口,你就不會讓調度員感到困惑......

這個小寶石檢查是否甚至有一個窗口。 如果沒有,請使用 MainView 的 Dispatcher。 如果有視圖,請使用該視圖的 Dispatcher。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM