public async void Run(IBackgroundTaskInstance taskInstance) { // Create the baconit manager m_baconMan = new BaconManager(true); // Setup the ref counted deferral RefCountedDeferral refDeferral = new RefCountedDeferral(taskInstance.GetDeferral(), OnDeferralCleanup); // Add a ref so everyone in this call is protected refDeferral.AddRef(); // Fire off the update await m_baconMan.BackgroundMan.RunUpdate(refDeferral); // After this returns the deferral will call complete unless someone else took a ref on it. refDeferral.ReleaseRef(); }
/// <summary> /// Kicks off an update of the images. /// </summary> /// <param name="force"></param> public async Task RunUpdate(RefCountedDeferral refDeferral, bool force = false) { if ((IsDeskopEnabled || IsLockScreenEnabled || IsBandWallpaperEnabled) && UserProfilePersonalizationSettings.IsSupported()) { TimeSpan timeSinceLastRun = DateTime.Now - LastImageUpdate; if(timeSinceLastRun.TotalMinutes > UpdateFrquency || force) { // Make sure we aren't running lock(this) { if(m_isRunning) { return; } m_isRunning = true; } // Do the updates await KickOffUpdate(force, refDeferral); } } }
/// <summary> /// Checks if we should update and if so does so. /// </summary> /// <param name="refDeferral"></param> /// <param name="force"></param> public void RunUpdate(RefCountedDeferral refDeferral, bool force = false) { if (IsEnabled && m_baconMan.UserMan.IsUserSignedIn) { TimeSpan timeSinceLastRun = DateTime.Now - LastUpdateTime; if (timeSinceLastRun.TotalMinutes > 10 || force) { // We should update. Grab the deferral m_refDeferral = refDeferral; m_refDeferral.AddRef(); // Make the collector m_collector = new MessageCollector(m_baconMan); // We don't need to sub to the collection update because we will get // called automatically when it updates m_collector.OnCollectorStateChange += Collector_OnCollectorStateChange; // Tell it to update! m_collector.Update(true); } } }
/// <summary> /// This will actually kick off all of the work. /// </summary> public async Task RunUpdate(RefCountedDeferral refDefferal) { // If we are a background task report the time if (m_baconMan.IsBackgroundTask) { LastUpdateTime = DateTime.Now; } // If we are not a background task check message of the day if(!m_baconMan.IsBackgroundTask) { // Sleep for a little while to give the UI some time get work done. await Task.Delay(1000); // Check for MOTD updates. await m_baconMan.MotdMan.CheckForUpdates(); // Sleep for a little while to give the UI some time get work done. await Task.Delay(5000); } // Ensure everything is ready await EnsureBackgroundSetup(); // Run the image update if needed await ImageUpdaterMan.RunUpdate(refDefferal); // Run the message update if needed. MessageUpdaterMan.RunUpdate(refDefferal); }
/// <summary> /// Releases the deferral if it is held. /// </summary> private void ReleaseDeferal() { if(m_refDeferral != null) { m_refDeferral.ReleaseRef(); } m_refDeferral = null; }
/// <summary> /// Called by the app when the app is suspending /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void OnSuspending_Fired(object sender, SuspendingEventArgs e) { // Setup a ref deferral for everyone to hold. We also need to setup a clean up action to save the setting // when the deferral is done. RefCountedDeferral refDeferral = new RefCountedDeferral(e.SuspendingOperation.GetDeferral(), () => { // We need to flush the settings here just before we complete the deferal. We need to block this function // until the settings are flushed. using (AutoResetEvent are = new AutoResetEvent(false)) { Task.Run(async () => { // Flush out the local settings await SettingsMan.FlushLocalSettings(); are.Set(); }); are.WaitOne(); } }); // Add a ref to cover anyone down this call stack. refDeferral.AddRef(); // Make the OnSuspendingArgs args = new OnSuspendingArgs() { RefDeferral = refDeferral }; // Fire the event m_onSuspending.Raise(this, args); // Release our ref to the deferral refDeferral.ReleaseRef(); }
/// <summary> /// Actually does the update /// </summary> private async Task KickOffUpdate(bool force, RefCountedDeferral refDeferral) { m_baconMan.TelemetryMan.ReportLog(this, "Updater updating."); try { // Figure out if we need to do a full update int fullUpdateFequencyMins = UpdateFrquency * c_maxImageCacheCount; TimeSpan timeSinceLastFullUpdate = DateTime.Now - LastFullUpdate; if (timeSinceLastFullUpdate.TotalMinutes > fullUpdateFequencyMins || force) { m_baconMan.TelemetryMan.ReportLog(this, "Running full update"); // Update lock screen images if (IsLockScreenEnabled) { m_baconMan.TelemetryMan.ReportLog(this, "Updating lock screen", SeverityLevel.Verbose); // Make a deferral scope object so we can do our work without being killed. // Note! We need release this object or it will hang the app around forever! m_lockScreenRefDeferral = refDeferral; m_lockScreenRefDeferral.AddRef(); // Kick off the update, this will happen async. GetSubredditStories(LockScreenSubredditName, UpdateTypes.LockScreen); } if(IsDeskopEnabled) { m_baconMan.TelemetryMan.ReportLog(this, "Updating lock screen", SeverityLevel.Verbose); // Shortcut: If lock screen in enabled and it is the same subreddit just share the same cache. If not, // get the desktop images if (IsLockScreenEnabled && LockScreenSubredditName.Equals(DesktopSubredditName)) { m_baconMan.TelemetryMan.ReportLog(this, "Desktop same sub as lockscreen, skipping image update.", SeverityLevel.Verbose); } else { m_baconMan.TelemetryMan.ReportLog(this, "Updating desktop image", SeverityLevel.Verbose); // Make a deferral scope object so we can do our work without being killed. // Note! We need release this object or it will hang the app around forever! m_desktopRefDeferral = refDeferral; m_desktopRefDeferral.AddRef(); // Kick off the update, this will happen async. GetSubredditStories(DesktopSubredditName, UpdateTypes.Desktop); } } // Update lock screen images if (IsBandWallpaperEnabled) { m_baconMan.TelemetryMan.ReportLog(this, "Updating band wallpaper", SeverityLevel.Verbose); // Make a deferral scope object so we can do our work without being killed. // Note! We need release this object or it will hang the app around forever! m_bandRefDeferral = refDeferral; m_bandRefDeferral.AddRef(); // Kick off the update, this will happen async. GetSubredditStories(BandSubredditName, UpdateTypes.Band); } } // Else full update else { m_baconMan.TelemetryMan.ReportLog(this, "No need for a full update, just rotating."); // If we aren't doing a full update just rotate the images. await DoImageRotation(UpdateTypes.All); // Stop the running state lock (this) { m_isRunning = false; } } } catch(Exception e) { m_baconMan.MessageMan.DebugDia("Failed to set background image", e); m_baconMan.TelemetryMan.ReportUnExpectedEvent(this, "Failed to set background image", e); } }
/// <summary> /// Release the deferral for a type if it is held /// </summary> /// <param name="type"></param> private void ReleaseDeferral(UpdateTypes type) { lock(this) { if (type == UpdateTypes.LockScreen) { if (m_lockScreenRefDeferral != null) { m_lockScreenRefDeferral.ReleaseRef(); } m_lockScreenRefDeferral = null; } else if(type == UpdateTypes.Band) { if (m_bandRefDeferral != null) { m_bandRefDeferral.ReleaseRef(); } m_bandRefDeferral = null; } else { if (m_desktopRefDeferral != null) { m_desktopRefDeferral.ReleaseRef(); } m_desktopRefDeferral = null; } } }