我正在使用Windows Phone 8.1上的加速度计
传感器。我必须从传感器的ReadingChanged
回调中访问UI。我还有一个DispatcherTimer
,每两秒更新一次传感器的ReportInterval
。当计时器触发并尝试设置加速度计的ReportInterval时,程序会阻塞。下面的示例是一个最小可执行示例,可以重现此错误。
namespace TryAccelerometer
{
public sealed partial class MainPage : Page
{
private Accelerometer acc;
private DispatcherTimer timer;
private int numberAcc = 0;
private int numberTimer = 0;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
acc = Accelerometer.GetDefault();
acc.ReadingChanged += acc_ReadingChanged;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += timer_Tick;
timer.Start();
}
async void acc_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args)
{
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
//HERE I WILL HAVE TO ACCESS THE UI, BUT FOR SAKE OF SIMPLICITY I WROTE AN INCREMENT
numberAcc++;
});
}
void timer_Tick(object sender, object e)
{
numberTimer++;
//PUT A BREAKPOINT HERE BELOW AND SEE THAT THE PROGRAM BLOCKS
acc.ReportInterval = acc.ReportInterval++;
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
}
}
我不明白死锁为什么会发生。谢谢您提前。
Accelerometer.GetDefault
之前尝试访问CoreWindow.Dispatcher
。一些 XAML 框架会按需创建分派程序,如果ReadingChanged
在分派程序循环开始之前触发,则可能会导致奇怪的问题。 - Stephen Cleary