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

时间:2017-08-14 16:01:24

标签: c# uwp win-universal-app

我在使用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和其他异步库,它们在事件触发器上有类似的问题。

1 个答案:

答案 0 :(得分:0)

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

此类在应用程序启动时设置对Dispatcher的静态引用,然后在您需要的任何地方使用它(例如,正是我想要的 - GetCurrentView()应该做的事情)

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

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