Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
3
Question by nventimiglia · Sep 24, 2011 at 09:11 PM · coroutineasyncthreading

Using AsyncOperation for our own services

I have a service which handles data saving / loading. The methods on this service might take a few seconds (if not more) to complete. What is the standard operating procedure for calling this service without freezing the UI?

I noticed that the "baked in" services (LoadLevelAsync) return an AsyncOperation. alowing them to easily incorporate the service into a coroutine :

ala

 var async = Application.LoadLevelAsync("myLevel");
 yield return async;
 // continue


This is a elegant solution, and prefer this to passing an oncomplete callback into my service or messing around with a background worker. Is there any way I can acquire this pattern for my own services? If not, any solution would be helpful.

Comment
Add comment · Show 3
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 nventimiglia · Sep 24, 2011 at 09:22 PM 0
Share

http://channel9.msdn.com/events/PDC/PDC10/FT09 Please add c#5 (I know, i know)

avatar image cregox · Oct 10, 2011 at 08:44 PM 0
Share

related: http://answers.unity3d.com/questions/56571/applicationloadlevelasync-not-working-in-unity-33.html

avatar image cregox · May 27, 2013 at 11:46 PM 0
Share

also, this might shred some light for you. after a long while, it did for me: http://stackoverflow.com/questions/12224602/a-method-for-making-http-requests-on-unity-ios/12606963#12606963

4 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by msknapp · Sep 25, 2011 at 04:09 AM

I personally felt that the Unity documentation on Coroutines was horrible. It took me a long time to figure out how to use them. Let me tell you one thing, do not use the .net thread classes for multi-threading, it won't work. Instead, you can write your own method that produces an IEnumerable instance. You can start a coroutine that uses that function:

Read this page to understand how to write your own function:

http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx

Here is my C# example:

    public System.Collections.IEnumerable coroutineFunction() {
     
         while (! doneYourPersistentProcess())
             // ... wait for it ...
             yield return "";
         // now it is done.
         doPostProcessing();
     
     }
     
     public void doPostProcessing() {
         // your code here.
     }
     
     public void Update() {
        if (userStartsPersistentProcess())
            StartCoroutine(coroutineFunction());
     
     }
     
     public bool userStartsPersistentProcess() {
         // your code here.
     }
 
     public bool doneYourPersistentProcess() {
         // your code here.
     }
Comment
Add comment · Show 2 · 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 appearance · Mar 06, 2013 at 12:51 PM 0
Share

I think your answer is correct as Richard Fine gives an insider look into Unity's Coroutines here.

avatar image CasualT · Mar 06, 2013 at 03:58 PM 0
Share

I wanted to clarify that you CAN use regular threads inside of a Unity app. We use functions like System.Threading.ThreadPool.QueueUserWorkItem in our app to handle async tasks. One thing to keep in $$anonymous$$d is that some Unity operations cannot be performed outside of the main thread, such as object comparisons, so your activities are a bit limited. And any error or unhandled exception that your thread comes across will NOT be reported in the Unity log. So you'll need to handle that aspect yourself.

avatar image
2

Answer by CasualT · Jan 09, 2013 at 08:57 PM

So here's another way of describing how to make a yieldable object:

 class YieldableObject
 {
     public Coroutine SlowFunction()
     {
         return StartCoroutine(WaitForSlowFunction);    
     }
 
     private IEnumerator WaitForSlowFunction()
     {
         while(!slowFunctionIsNotDone)
         {
             yield return null;
         }
     }
 }
 
 
 
 class MainApp()
 {
     IEnumerator CallingFunction()
     {
         YieldableObject yielder = new YieldableObject();
         yield return yielder.SlowFunction();    // Will wait here for the operation to finish
     }
 
     void Main()
     {
         StartCoroutine(CallingFunction());
     }
 }

Here, Main() will start a Coroutine of CallingFunction which will create and yield to your YieldableObject while it is performing the SlowFunction. SlowFunction does whatever operation it needs to, but must have another StartCoroutine in it. The first Coroutine will pause execution and wait until the "inner" Coroutine is finished. That's the secret to getting a yield to wait for your operation to complete, similar to how Unity's built-in WWW class works.

Comment
Add comment · Show 2 · 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 Olly · May 12, 2016 at 05:23 PM 1
Share

Can you give a working example of what would be in slow function?

avatar image ryvianstyron · Sep 29, 2016 at 11:11 AM 0
Share

Hi CasualT, I was interested in your implementation but was wondering if it could be applied to my own unique code scenario. I felt the need to explain it properly so I listed it as a Separate Question Here to gain insight from you and other Unity users on some direction to the implementation I need.

avatar image
1

Answer by dkozar · Feb 02, 2013 at 08:55 PM

There is the asynchronous way of doing things in Unity without using of coroutines. Check out the eDriven library and this video: http://www.youtube.com/watch?v=KytO48w7fOI

eDriven: https://github.com/dkozar/eDriven

Comment
Add comment · 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
0

Answer by nventimiglia · Aug 04, 2012 at 07:39 PM

Yeah I ran in to a similar need this week. I was cleaning up my Service Model which included several async operations (Login, GetScores, ect). Moreover these services are separate from my viewmodels which invoke them.

My solution was to expose a public IEnumerator coroutine and state variable in my service.

 public class MyAccountService : MonoBehaviour
 {
     public bool IsAuthenticated { get; protected set; }
 
     public IEnumerator Login()
     {
         yield return 1;
 
         IsAuthenticated = true;
     }
 }
 
 public class MyViewModel : MonoBehaviour
 {
 
     public MyAccountService Service;
 
     void Awake()
     {
         StartCoroutine(OnReady());
     }
 
     public IEnumerator OnReady()
     {
         yield return 1;
         
         yield return StartCoroutine(Service.Login());
 
         if (Service.IsAuthenticated)
         {
             //blah
         }
     }
 }
Comment
Add comment · 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

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

10 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

Related Questions

Saving data question 1 Answer

Threading in Unity 6 Answers

Loading screen with async load and freezing gameplay 0 Answers

Help needed with WaitForSeconds() 2 Answers

Why does accessing www.text blocks the coroutine using WWW class? 1 Answer


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