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

Invoke a function after hours?

Discussion in 'Scripting' started by Unlimited_Energy, Nov 17, 2019.

  1. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    I was wondering if there is a performance impact for an invoke function that is fired every couple hours or daily. I need to get the Timezone and current time of the user and serialize the current time at game launch. If it has been past the specified wait time of x hours since last game launch for that users timezone/time then I need to fire a function. This is for a daily task type of implementation in the game.

    However, it also needs to be able to fire the event in the game if the user so happens to be in the game runtime and the event has reached the X amount of time specified to invoke the function.

    I was thinking of using invoke repeating and if the user closes the game that it serializes the amount of time passed in invoke repeating since the function first fired, the current time in hours and days then add the difference of the time from last launch to the current session and Start InvokeRepeating with the difference added if it is under the time to lnvoke the function(say if the user logs in 2 hours later), if it has passed the invoke time(user logs in next day) then bypass the invoke and fire immediately, then start invoke repeating again.

    What is the performance impact of long invoke repeating functions, ones with an invoke delay of hours and is there an more efficient method of doing this? Not sure if stuffing a check of the current time inside a late update method with long delays between frame checks would be better..
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    I dont know how invoke is implemented, but i would imagine that it's effectively checking every cycle if the time based condition is met, to call a function. So the performance impact should be independant of how long the waiting time is.
    Take the above with a grain of salt, since i'm not entirely sure if there are any optimizations for invoke that rely on lower timings. However, if your intention is to only call a function after a long period of time, you could write your own thread (getting the task off the main thread) that sleeps most of the time, wakes up once every couple seconds, checks if enough time passed and then either returns to sleeping or calls your function. Since it's off the main thread, this wouldnt affect performance 'at all'. One disadvantage would be that you cant really access most of the Unity API outside of the main thread. So it depends on what you want to do.

    That said, why not simply test invoke with extremely large time values and see if you spot a performance hit in the inspector? If you cant see it in the numbers, dont worry about it. And if you see it, you could just have a Monobehavior check for the time condition every Update() cycle, which is a neglectable effort every couple milliseconds (frame).
     
    Unlimited_Energy likes this.
  3. Grankor

    Grankor

    Joined:
    Mar 2, 2015
    Posts:
    14
    Is this server side code, or client code?

    Assuming it's client side code:
    Using an Invoke (on a task I assume?) is reasonably reliable if it's not 'terribly' long. There aren't necessarily performance issues, but reliability issues in my experience.

    Perhaps you could implement something like this?
    If you have a set 'thing' that needs to happen, save the time you need it to happen to local storage.
    Set the time like this.
    Code (CSharp):
    1. var timeThingNeedsToHappen = DateTime.DateTime.UtcNow.AddMinutes(120);
    Then save it to local storage.
    Then while the user is active, you have have a function that pulls that date and monitors the time until it's supposed to happen.
    If you have a game manager, you can place it in there.

    Code (CSharp):
    1. if (thingThatsSupposedToHappen < DateTime.DateTime.UtcNow)
    2. {
    3.     //Do Stuff
    4.  
    5.    /maybe reset thingThatsSupposedToHappen
    6. }
     
    Unlimited_Energy likes this.
  4. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    As long as you don't have thousands of script that do this, don't think about it. The performance overhead of a single InvokeRepeating is minuscle, and you are about to engage in premature optimization.
     
    Unlimited_Energy likes this.