2014-01-10 24 views
1

我在写一个Windows Phone 8应用程序,它使用Geolocator来跟踪您的位置。我使用MS示例代码作为基础并对其进行了调整。我有一个问题,当应用程序在后台运行时,我想偶尔发布Toast消息来通知用户一些信息。我有这个工作正常,但是当用户试图打开应用程序备份(并将应用程序从'RunningInBackground'返回到前台时发生问题。我有一个'无限'循环,它有一个突破点,但它似乎锁定在主线程和避免回到过去了不再在后台运行的应用程序Windows Phone Thread.Sleep防止在后台运行时加载UI

下面是我在主要XAML页面运行代码的样本:

// The PositionChanged event is raised when new position data is available 
    void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args) 
    { 
     CurrentPosition = args.Position; 

     if (!App.RunningInBackground) 
     { 
      Dispatcher.BeginInvoke(() => 
      { 
       // TODO: HANDLE POSITION CHANGES 
       LatitudeTextBlock.Text = args.Position.Coordinate.Latitude.ToString("0.00"); 
       LongitudeTextBlock.Text = args.Position.Coordinate.Longitude.ToString("0.00"); 
      }); 
     } 
     else 
     { 
      // ReadyToSend is a bool that is set further below, CheckingIfReadyToSend is a bool to prevent this bit of code from running more than once at a time 
      if (!ReadyToSend && !CheckingIfReadyToSend) 
      { 
       CheckingIfReadyToSend = true; 
       Dispatcher.BeginInvoke(() => 
       { 

        ReadyToSend = _viewModel.CheckIfNeedToStartNotifying(); 

        if (ReadyToSend) 
        { 
         StartToastCycle(3); 
        } 
        CheckingIfReadyToSend = false; 
       }); 

      } 


     } 
    } 

private void StartToastCycle(int MaxNotifications) 
    { 
     while (App.RunningInBackground) 
     { 
      if (NotificationCount >= MaxNotifications || !App.RunningInBackground) 
       break; 
      if (NotificationCount < MaxNotifications && NotificationLastSent < DateTime.Now.AddMinutes(-2)) 
      { 
       Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast(); 
       toast.Content = "Test"; 
       toast.Title = "Test: "; 
       toast.NavigationUri = new Uri("/Views/HomePage.xaml", UriKind.Relative); 
       toast.Show(); 
       NotificationCount++; 
       NotificationLastSent = DateTime.Now; 
      } 

      System.Threading.Thread.Sleep(10000); 


     } 
    } 

因此,上面的代码工作,它会触发StartToastCycle方法,当满足一定条件时,它会每2分钟发送Toast Notifications,直到它达到MaxNotifications。唯一的问题是,如果我点击Toast通知从后台加载应用程序(在MaxNotifications条件满足之前),它仍停留在该循环中。

在App.xaml.cs的Application_Activated事件中,我将bool IsRunningInBackground设置为false不会被击中。

关于如何在代码中触发吐司处理程序但不锁定主线程的任何想法?

任何意见非常感谢!

回答

3

答案是async

您需要制作StartToastCycleasync,然后让它在await a Task.Delay的时间量内。

private async void StartToastCycle(int MaxNotifications) 
{ 
    while (App.RunningInBackground) 
    { 
     if (NotificationCount >= MaxNotifications || !App.RunningInBackground) 
      break; 
     if (NotificationCount < MaxNotifications && NotificationLastSent < DateTime.Now.AddMinutes(-2)) 
     { 
      Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast(); 
      toast.Content = "Test"; 
      toast.Title = "Test: "; 
      toast.NavigationUri = new Uri("/Views/HomePage.xaml", UriKind.Relative); 
      toast.Show(); 
      NotificationCount++; 
      NotificationLastSent = DateTime.Now; 
     } 
     await Task.Delay(TimeSpan.FromSeconds(10)); 

    } 
} 

现在,我不知道是否需要在UI线程上发送吐司。在这种情况下,您需要保留Dispatcher对象的副本并在UI线程上调用敬酒(就像您在顶层方法中所做的那样)。您可能需要对此进行一些实验。

希望帮助和快乐的编码!

+0

当然!我不敢相信我没有想到异步!想想我一直在盯着这个问题太久了!非常感谢! – Stevieboy84