- Home /
 
Does passing an Action as a parameter create garbage?
I'm using a "timer" script that takes an action as a parameter. The script calls the Action when the timer is complete. Does passing an action in a parameter create garbage? I use this a lot and im getting a bunch of GC.Collect() calls in the profiler and it's coming from my timer classes.
Here's what it looks like:
 public class Timer : MonoBehaviour
 {
     private float _timer;
     private float _maxTime;
     public void StartTimer(float time, Action callback) 
     { 
          _timer = 0;
         _maxTime = time;
         TimerCompleteCallback = callback;  
     }
     ////////// Some update code //////////////////////
     void TimerEnd() 
     {  
         this.enabled = false;
         TimerCompleteCallback();
     }
 }
 
 public class OtherClass : MonoBehaviour
 {
      private Timer _timer;
      void Start()
      {
          _timer = gameObject.AddComponent<Timer>();
          _timer.StartTimer(5, OnTimerComplete);
      }
                 
     void OnTimerComplete()
     {
         // Will this timer loop end up creating garbage?
         _timer.StartTimer(5, OnTimerComplete);
     }
 }
 
              Answer by landon912 · Sep 30, 2015 at 11:40 PM
Fun! Here is your issue:
 _timer.StartTimer(5, OnTimerComplete);
 
               This seems to be inlined to be:
 _timer.StartTimer(5, () => OnTimerComplete);
 
               Therefore this is creating a new delegate each time you start the timer. If you cache the delegate this is solved:
 public class OtherClass : MonoBehaviour
 {
       private Timer _timer;
       private Action _action;
 
       void Start()
       {
           _timer = gameObject.AddComponent<Timer>();
          _action = OnTimerComplete;
           _timer.StartTimer(5, _action);
       }
                  
      void OnTimerComplete()
      {
          // Will this timer loop end up creating garbage?
          _timer.StartTimer(5, _action);
      }
  }
 
 
               Hope this helps!
For reference, here is my test:
 using System;
 using UnityEngine;
 
 public class ActionDelegateGarbageTest : MonoBehaviour
 {
     private Action mAction;
 
     public void Start ()
     {
         mAction = () => EventReciever ();
     }
 
     public void Update ()
     {
         //doesn't create garbage
         //PassTest (mAction);
 
         //creates garbage
         //PassTest (EventReciever);
     }
 
     private void PassTest (Action actionToComplete)
     {
         actionToComplete();
     }
 
     private void EventReciever()
     {
         
     }
 }
 
              Thank you from 2021. I was racking my brain trying to figure out the same issue!
Your answer
 
             Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Add an iteration of OnClick methods 1 Answer
When to use 'delegate', 'event' or 'Action' ? 1 Answer
Adding a function to a UI 4.6 Button called on another game object in c# 0 Answers