Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

OnApplicationPause (Wait until coroutines complete)

Discussion in 'Scripting' started by alexpoolton, Jun 18, 2015.

  1. alexpoolton

    alexpoolton

    Joined:
    Nov 25, 2013
    Posts:
    6
    Hi guys,

    Is there a way to wait until a series of coroutines completes, before the app suspends?

    I'm suspending the app, the coroutines start, but don't finish, and then complete once the app is resumed. I basically want to complete all the coroutines before the app finally suspends.

    Is this possible?
     
  2. chubbspet

    chubbspet

    Joined:
    Feb 18, 2010
    Posts:
    1,220
    You will have to use a static bool in the "pausable" code to check if there are coroutines running.
     
  3. alexpoolton

    alexpoolton

    Joined:
    Nov 25, 2013
    Posts:
    6
    Code (CSharp):
    1. void OnApplicationPause(bool isPaused)
    2. {
    3.     if(Application.loadedLevelName == GameData.SCENE_NAME_MATCHCHANCE_LEVEL)
    4.     {
    5.         if(isPaused)
    6.         {
    7.             // Get current server time and update lastActive time for user
    8.              
    9.        StartCoroutine(ParseManager.Instance.GetCurrentUTCServerTime((isGetCurrentTimeSuccessful, currentTime) =>
    10.             {
    11.             if(isGetCurrentTimeSuccessful)
    12.             {
    13.                 ParseUser.CurrentUser["lastActive"] = currentTime;
    14.  
    15.                 StartCoroutine(ParseManager.Instance.SaveCurrentUser());
    16.  
    17.                  // Set the current incomplete match
    18.                  TeamManager.ActiveTeam.SetIncompleteMatch((int)MatchStateController.Instance.CurrentMinute, MatchStateController.Instance.MatchDetails);
    19.  
    20.               StartCoroutine(TeamManager.Instance.SaveActiveTeam());
    21.               }
    22.      }));
    23.      }
    24.   }
    25. }
    Here's my OnApplicationPause method, hopefully that has formatted correctly.

    I'm not quite sure how that will work (the static bool). Do you mean in the first if statement, add a bool "AreCoroutinesRunning" that only gets set to false once the last coroutine is finished?

    Just to give you some insight into the code, it's a series of coroutines (that use callbacks) to move onto the next coroutine.
     
  4. chubbspet

    chubbspet

    Joined:
    Feb 18, 2010
    Posts:
    1,220
    just to make sure, how are you testing this? You know that the pause button in the editor does not work? You need to loose focus of the unity editor. Just wanted to make sure... also, remember that this function is not going to actually pause you game. It is just an event that is called when the game pauses, so you need to handle the actual pause of your game in code by e.g. setting time to 0, disabling scripts etc.
     
  5. alexpoolton

    alexpoolton

    Joined:
    Nov 25, 2013
    Posts:
    6
    Yep I've tested by losing focus in the editor.

    I added a simple Debug.Log("Test") for both isPaused and else (aka not paused). Which is working fine. The problem I'm having is:

    1) When suspending the app (isPaused) the coroutine starts to run, but doesn't complete
    2) When resuming the app (!isPaused) the coroutine from the isPaused block will continue and finish to run (which I don't want).

    I want the entire block (including coroutines) to finish when suspending the app, which isn't the case atm.

    I'm not sure, if that's because they run on a separate thread and only the main thread is forced to finish when suspending the app. Or if there simply isn't enough time for them to finish while the app is being suspended.

    Hopefully there's a way I can yield until they finish and then allow the app to suspend.
     
  6. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    What platform are you targeting? I think I read that iOS will not allow lengthy suspension delays.
    Does implementing OnApplicationPause as a coroutine help you?
    Does your target platform allow to be run in background and could that help you?
     
  7. chubbspet

    chubbspet

    Joined:
    Feb 18, 2010
    Posts:
    1,220
    My understanding is that IEnumerators run on the main thread, which according to my (limited) knowledge, will stop all coroutines when the app is paused and continue when focus is re-gained. This means that you will have to 1) create your own thread or 2) look for a different approach and it also explains the behaviour you are getting.

    I'm calling it a night, hopefully by tomorrow morning you will have good news!
     
  8. alexpoolton

    alexpoolton

    Joined:
    Nov 25, 2013
    Posts:
    6
    @ThermalFusion I'm targeting iOS atm. Implementing OnApplicationPause as a coroutine looks like it suffers the same issue of not completing before the app suspends, but after. Also "RunInBackground" is only an option on standalone and web player builds.

    @chubbspet Yeah that sounds like exactly what is happening. I'll try running on a different thread, but failing that, it looks like I'll have to use a different solution.