在计时器回调中以锁屏(分配访问)模式获取调度程序
Getting Dispatcher in Lockscreen (Assigned-access) mode in a timer callback
我在使用 GetCurrentView() 方法获取调度程序时遇到了一些问题。如 MSDN 所述,如果我的应用程序在分配的访问模式下为 运行,我应该使用 CoreApplication.GetCurrentView()。
但是,在计时器回调中使用 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
我在使用 GetCurrentView() 方法获取调度程序时遇到了一些问题。如 MSDN 所述,如果我的应用程序在分配的访问模式下为 运行,我应该使用 CoreApplication.GetCurrentView()。
但是,在计时器回调中使用 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