Is clearing timers mandatory when we no longer need them?

Consider the following snippet in which I want to mimic SetLifeSpan() with a timer.

void AMyActor::BeginPlay()
{
    Super::BeginPlay();
    //SetLifeSpan(3.f);
    FTimerHandle th;
    GetWorldTimerManager().SetTimer(th, 
    [th,this]
    {
        GetWorldTimerManager().ClearTimer(th);
        this->Destroy();
    }
    , 3.f, false);
}

I always want to minimize the number of class members so I put the timer handle th as a local variable in BeginPlay(). I don’t know whether or not th is cheap.

If th is expensive then the lambda should capture th by reference. Unfortunately th is local in this scenario. Capturing it can cause dangling reference. Promoting th from local variable to class member variable can solve the dangling reference problem.

Questions

  • Is th cheap or expensive?
  • Is it mandatory to call GetWorldTimerManager().ClearTimer(); whenever we have finished using a timer?
  1. You can go to the definition and look at it’s privates (:wink:). You can see it’s just a handful of ints so should be cheap.
  2. If it wasn’t a handful of ints and was something that owns a resource like FString which can be moved you can move it into the capture e.g.
    [Str = MoveTemp(SomeStr)] { /* */ }
    
    Though you should ought to know more about move semantics regarding that. (e.g. you should know that MoveTemp does no moving whatsoever).
  3. I haven’t looked at the docs but I’d imagine that’s only needed if you have it repeating. I would expect a non-repeating timer to clean itself up after its done. Edit: I just noticed that you’re calling Destroy, if you have other timers on that actor then you probably ought to call ClearAllTimersForObject(this).
1 Like

Referring to your 3rd point above, is th (the instance of FTimerHandle) sharable? I meant, for example, I set a timer via an actor A with th and then clear th via another actor B as follows:

// Assume we have a member variable `th`, two actors `A` and `B` in a level script actor.
// Somewhere in the level script actor, I have the following
A->GetWorldTimerManager().SetTimer(th,...);
B->GetWorldTimerManager().ClearTimer(th);

Yes, it’s just an index into an array.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.