在计时器回调中以锁屏(分配访问)模式获取调度程序

Getting Dispatcher in Lockscreen (Assigned-access) mode in a timer callback

我在使用 GetCurrentView() 方法获取调度程序时遇到了一些问题。如 MSDN 所述,如果我的应用程序在分配的访问模式下为 运行,我应该使用 CoreApplication.GetCurrentView()。

https://msdn.microsoft.com/windows/hardware/drivers/partnerapps/create-a-kiosk-app-for-assigned-access

但是,在计时器回调中使用 GetCurrentView() 时会导致异常。

有人建议我如何让它在分配的访问模式下工作吗? 这是我的代码,其中包含关于什么有效和无效的注释。

sealed partial class App : Application
{
    private Timer timer;

    public App()
    {
        this.InitializeComponent();
    }

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        try
        {
            IsAssignedAccess = LockApplicationHost.GetForCurrentView() != null;
        }
        catch
        {
            IsAssignedAccess = false;
        }

        // This works fine
        OnTimerAsync();

        // From timer callback OnTimerAsync() doesn't work (see below)
        this.timer = new Timer((e2) => { OnTimerAsync(); }, null, (int)TimeSpan.FromSeconds(5).TotalMilliseconds,
            (int)TimeSpan.FromSeconds(5).TotalMilliseconds);

    }

    private async void OnTimerAsync()
    {
        if (App.IsAssignedAccess)
        {
            // This causes the app to crash in assigned access mode
            await CoreApplication.GetCurrentView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* void */ });
        }
        else
        {
            // This works fine in desktop mode, but doesn't work in assigned access mode (lockscreen app)
            await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { /* void */ });

            // This line below causes app to crash when called from timer callback, but works fine when called directly from OnLaunched();
            var curView = CoreApplication.GetCurrentView();
            /*
                * Exception details when called from timer callback
                * Exception thrown: 'System.Runtime.InteropServices.COMException' in LockScreenTest.exe
                * WinRT information: Kan element niet vinden. (Translated: Cannot find element)
                */

            var curDispatch = curView.Dispatcher;
            await curDispatch.RunAsync(CoreDispatcherPriority.Normal, () => { /* void */ });
        }
    }

    public static bool IsAssignedAccess { get; private set; }
}

PS。 这是一个带有计时器的示例,我也在使用 NFC/SmartCard 和其他在事件触发器上有类似问题的异步库。

我使用 MvvmLight 中的 DispatcherHelper class 代替 GetCurrentView() 方法解决了我的问题。

这个 class 在应用程序启动时设置对 Dispatcher 的静态引用,然后在您需要的任何地方使用它(例如,正是我认为的 GetCurrentView() 应该做的)

有关详细信息,请参阅这篇(优秀)文章:

http://msdn.microsoft.com/en-us/magazine/dn630646.aspx?f=255&MSPPError=-2147217396