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
2
Question by ronewolf · Jan 20, 2012 at 03:07 AM · coroutinethreadingcallback

Callback from a coroutine

I'm building a C# API for various network services. Currently my methods need to be polled to return data, but I'd like to upgrade this to have them trigger a developer-implemented callback.

I've established after some research that it is not safe to trigger a callback from a separate thread back into the main UnityEngine/MonoBehavior thread.

So my next thought - perhaps I can have my API take in the developer callback, start a coroutine but return immediately after, and eventually trigger the callback from the coroutine. I'm hoping to vet this idea before going too far down the rabbit hole, so I'll paste my proposed code below (somewhat pseudo) and if anyone has feedback as to whether or not this would be safe I'd greatly appreciate it.

Here is the example class that would contain the API:

 using UnityEngine;
 using System.Collections;
 
 public class DoAsynchronousStuff : MonoBehaviour
 {
     enum State {Pending, Complete};
     State state;
     
     // assume OutputData and InputData are classes defined elsewhere
     public delegate void Callback (OutputData data);
     
     public static void DoAThing(InputData data, Callback cb)
     {
         StartCoroutine(DoIt(data, cb));    
     }
     
     IEnumerator DoIt(InputData data, Callback callBack)
     {
         /* would be state machine here that hits a web service 
          * or something and updates state to Complete when a 
          * response is received (and populates an OutputData) */
         
         while (state != Complete)
             yield;
         
         callBack(outputData);
     }
 }

Then the developer implementation would look something like:

 using UnityEngine;
 using System.Collections;
 
 public class Sample : MonoBehaviour
 {
     OutputData outputData = null;
     InputData inputData;
     
     DoAsynchronousStuff.Callback myCallback = DidAThing;
     
     void DidAThing(OutputData data)
     {
         outputData = data; 
     }
     
     void Start()
     {
         // assume we've populated inputData already
         DoAsynchronousStuff.DoAThing(inputData, myCallback);
     }
     
     void Update()
     {
         if (outputData != null)
         {
             // do stuff with the data 
             
             outputData = null; // so we only do stuff with data once
         }
     }
 } 

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 syclamoth · Jan 20, 2012 at 03:09 AM 0
Share

Seems like a good way of doing things.

avatar image CarsonBikes · Jan 06, 2014 at 03:46 PM 0
Share

I was searching for a solution like yours, but unfortunately your code dosen't work if i use it the way it is. Unity gives me the following Errors: "error CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement" I then changed "yield;" to "yield return null;" and this error disappeard. Then came: "error CS0120: An object reference is required to access non-static member `UnityEngine.$$anonymous$$onoBehaviour.StartCoroutine(System.Collections.IEnumerator)'"

Can you help me get this to work?

avatar image kromenak · Jan 07, 2014 at 09:05 AM 0
Share

We had a similar issue to this where a third party library would fire callbacks not on the main thread, which would cause some tricky bugs. Our solution was essentially what you've got here - some sort of shared data set by the callback, which could then be checked by the main thread in a coroutine. So far, this has worked fine for us, so I'd say this looks solid.

Nice thing about a coroutine like that is you could also easily create time-out scenarios or use a timer to detect when a network operation is taking too long, and respond to it.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by edcarlo · Jan 07, 2014 at 07:11 AM

StartCoroutine & DoIt is a non-static. So DoAThing(...) must be non-static.

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

8 People are following this question.

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

Related Questions

C# lambda call in for loop references to last object 3 Answers

Coroutines, Threads and Level Generation? 2 Answers

C# How to wait on callback, should I use threading? 1 Answer

Is there any workaround to run corutines in an other thread? 1 Answer

Does UnityEngine.CustomeYieldInstruction works in a seperate thread? 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