Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
153 views
in Technique[技术] by (71.8m points)

c# - How to run a method in the background only when app is open and running?

Once the app is open and running I would like a background process to check a database and to make an update depending on the data in the database. I would like to make this check every one minute. I only want this to happen when the app is in the foreground and in view of the user.

Can someone give me some suggestions as to how I do this? I assume I can call a method from here but I'm not sure how to do this. Also I do not know how to stop or even if I need to manually cancel / stop the process. Would it cancel itself when the app is not in the foreground and restart when the app came back into the foreground?

public partial class App : Application
{

   protected override void OnStart()
   {
      App.DB.InitData();
      MainPage = new Japanese.MainPage();
   }

But do I need to make this run on a different thread and if so how could I do that.

Sorry if my question is not clear. Please ask and I can update if it doesn't make sense.

question from:https://stackoverflow.com/questions/45209784/how-to-run-a-method-in-the-background-only-when-app-is-open-and-running

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What we did in our forms application was to make use of the Device.Timer and the Stopwatch class that available in System.Diagnostics, and Xamarin.Forms to create a very generic managed timer that we could interact with using the onStart, onSleep and onResume methods in Xamarin.Forms.

This particular solution doesn't require any special platform specific logic, and the device timer and stopwatch are non UI blocking.

using Xamarin.Forms;
using System;
using System.Linq;
using System.Diagnostics;

namespace YourNamespace
{
    public partial class App : Application
    {
        private static Stopwatch stopWatch = new Stopwatch();
        private const int defaultTimespan = 1;

        protected override void OnStart()
        {
            // On start runs when your application launches from a closed state, 

            if (!stopWatch.IsRunning)
            {
                stopWatch.Start();
            }

            Device.StartTimer(new TimeSpan(0, 0, 1), () =>
            {
                // Logic for logging out if the device is inactive for a period of time.

                if (stopWatch.IsRunning && stopWatch.Elapsed.Minutes >= defaultTimespan)
                {
                    //prepare to perform your data pull here as we have hit the 1 minute mark   

                        // Perform your long running operations here.

                        Device.InvokeOnMainThread(()=>{
                            // If you need to do anything with your UI, you need to wrap it in this.
                        });

                    stopwatch.Restart();
                }

                // Always return true as to keep our device timer running.
                return true;
            });
        }

        protected override void OnSleep()
        {
            // Ensure our stopwatch is reset so the elapsed time is 0.
            stopWatch.Reset();
        }

        protected override void OnResume()
        {
            // App enters the foreground so start our stopwatch again.
            stopWatch.Start();
        }
    }
}


Edit:

To give some context as to how the above solution works step by step:

The application starts from a closed state and the 'OnStart()' method creates our Device.Timer that ticks every second. It also starts our stopwatch that counts upto a minute.

When the app goes into the background it hits the 'OnSleep' method at this point if we were to pass a 'false' value into our Device.StartTimer() action it would not start up again. So instead we simply reset our stopwatch ready for when the app is opened again.

When the app comes back into the foreground it hits the 'OnResume' method, which simply starts the existing stopwatch.

2018 Edit:

This answer still has some merits even in 2018, but mainly for very specific situations. There are better platform specific ways to replicate this functionality even in Xamarin.Forms. The above still remains a platform agnostic way to perform a task after a period of time, taking into account user activity/inactivity.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...