Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
16
Question by Fliperamma · Aug 29, 2012 at 12:49 AM · coroutinestartcoroutinestack

Calling StartCoroutine multiple times seems to stack

Hello there. I'm new to C# and I noticed that if you call StartCoroutine multiple times the Coroutine seems to stack. I just want to know if this is a expected behavior.

I managed to "solve" this by using StopCoroutine("MethodName") BEFORE StartCoroutine("MethodName").

In the example bellow if I use OneCall the Amount result is around 535, if I use TwoCalls the result is around 1035 .. and so on :

 using UnityEngine;
 using System.Collections;
 
 public class CoroutineTest : MonoBehaviour {
     // true means that the StartCoroutine will be called once. 
     public bool OneCall = true;
     // true means that the StartCoroutine will be called twice.
     public bool TwoCalls = false;
     // Time in seconds that the test will be running.
     public float TestTime = 10f;
     // While looping times
     public int Amount = 0;
     
     
     void Start () {
                 // First call
         StartCoroutine(Test ());
                 // Second call (activate it in the Unity Editor)
         if(TwoCalls)StartCoroutine(Test ());
         StartCoroutine (StopTest());
     }
     
 
     IEnumerator StopTest()
     {
         yield return new WaitForSeconds(TestTime);
         OneCall = false;
     }
 
     
     IEnumerator Test()
     {
         Amount = 0;
         while(OneCall){
             ++Amount;
             yield return null;
         }
     }
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
45
Best Answer

Answer by aldonaletto · Aug 29, 2012 at 02:19 AM

Yes, coroutines run independently, like separate threads. When you start a coroutine, an instance of it is created and starts running. If you start the same coroutine again, another instance is created and runs independently of the other, and so on.
This is a blessing in some special cases, but much more often may become a curse: if you start a coroutine each Update, for example (a very common error), a new instance will be created each frame, crowding the memory and eating the CPU time in a few minutes. To avoid this, a solution is to use a boolean variable that's set when the coroutine starts and cleared upon finish, and check this variable before starting a the coroutine again - like this:

 bool isRunning = false;

 IEnumerator MyCoroutine(){
   isRunning = true;
   print("started");
   yield return new WaitForSeconds(3);
   print("3 seconds elapsed");
   yield return new WaitForSeconds(3);
   print("more 3 seconds");
   yield return new WaitForSeconds(2);
   print("ended");
   isRunning = false;
 }

 void Update(){
   if (!isRunning) StartCoroutine(MyCoroutine());
 }


This code will call MyCoroutine repeatedly, but only one instance at a time due to the flag isRunning - if you don't check it, a new MyCoroutine will be created each frame. At 50 frames per second, for instance, you may have about 400 MyCoroutine instances running at the same time (each one lives for 8 seconds).

Comment
Add comment · Show 10 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fliperamma · Aug 29, 2012 at 03:23 AM 0
Share

Thank you Aldo!

avatar image Kryptos · Aug 29, 2012 at 08:00 AM 10
Share

No coroutines are nothing like threads. They do not run independently but sequentially.

They work exactly like processes in a non-preemptive multitasking operating system (also known as cooperative multitasking).

The next coroutine in the queuing scheduler will not run until the current one yields.

Your answer is a little misleading.

avatar image Kryptos · Aug 29, 2012 at 12:27 PM 2
Share

Not quite. The main difference is that with preemptive multitasking there is no way to know when a context change will appear. With coroutines it appears at the yield instruction.

This can look like a small difference, but it has completely different consequences. And it requires some other approaches that are sometimes opposite.

I insist on this point to avoid misuse of recipes or solutions of problems regarding threads in the context of coroutines.

The rest of your answer is correct when you explain the creation of coroutine instances.

avatar image DLBit · Jan 02, 2016 at 08:29 AM 3
Share

This boolean variable may become another problem if the coroutine is stopped manually or by deactivating the object. Then the variable will not be set to false because the coroutine will never finish. Should be used with caution.

avatar image LukeNukem44 · May 10, 2019 at 09:50 AM 1
Share

Aldo, you could have left it at, It's a blessing, as, it is, considering Unity made it unattractive to use new Threads in Unity. The next 2/3s you hammer the point of obviously not starting Coroutines every frame, which the poster seems to know by the given example.


$$anonymous$$ryptos, of course in simple terms Coroutines are like threads for Unity, which is a plain blessing. The end user doesn't give two hoots about whether you implemented a new Thread or Coroutine in your awesome game, only that it works and the end result is the same. -- When I compare my Console app with a ticking Thread and an Input Thread with two Unity Coroutines that show similar output, the results are the same, therefore, learn some Earth language => Coroutines are LI$$anonymous$$E Threads. (That's a surface statement, which is 100% true!) You really don't need to be a Nazi about the irrelevant workings of each!!!

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Item duration doesn't stack 3 Answers

I can't start a coroutine. I get a weird message from visual studio 1 Answer

Coroutines IEnumerator not working as expected 2 Answers

How to force Coroutine to finish 1 Answer

Startcoroutine not working second time 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges