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
1
Question by ghostravenstorm · Jun 04, 2020 at 09:19 PM · coroutinethreadsudpblocking

Blocking method calls in a coroutine?

Can blocking calls be used in a coroutine without it stopping the main thread? I have a MonoBehaviour that is designed to send a UDP broadcast to obtain a server IP address on LAN that is listening for the broadcast. In my coroutine, I'm executing a UDPClient.Recievemethod to get back a message, and it seems to be halting my main thread entirely despite my correct use of yield statements.

 UdpClient client = new UdpClient();

 Coroutine discoverAddress;
 IEnumerator DiscoverAddress (
    float timeout,
    OnAddressDiscovered onAddressDiscovered,
    OnTimeout onTimeout
 ) {
 
    float timeWaited = 0;
 
    yield return null;
 
    for (;;) {
       if (timeWaited >= timeout) break;
 
       string address = AskForAddress();
       if (address != null || address != "") {
          onAddressDiscovered(address);
          StopCoroutine(discoverAddress);
       }
 
       timeWaited += Time.deltaTime;
       yield return null;
    }
 
    onTimeout();
    client.Close();
 }
 
 string AskForAddress () {
    IPEndPoint serverEp = new IPEndPoint(IPAddress.Any, 0);
 
    client.EnableBroadcast = true;
    byte[] requestData = Encoding.ASCII.GetBytes("SomeRequestData");
 
    client.Send(
       requestData,
       requestData.Length,
       new IPEndPoint(IPAddress.Broadcast, udpPort)
    );
 
    byte[] serverResponseData = client.Receive(ref serverEp);
    string serverResponse = Encoding.ASCII.GetString(serverResponseData);
 
    return serverEp.Address.ToString();
 }

 
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
0

Answer by Bunny83 · Jun 05, 2020 at 09:44 AM

No, they can not be used since a coroutine is a "cooperative routing" which runs on the main thread and requires cooperation by the routine in order to keep the the rest of the code in the thread running. When the execution is yielded to your coroutine, your coroutine is the only thing running at that moment (of course on the main thread only). Other parts of the main thread can only continue when your coroutine uses the yield statement at which point your coroutine is essentially suspended and the execution is yielded back to Unity. As long as you don't yield your main thread is stuck in your coroutine.


Any kind of direct networking has to be done on a seperate thread. You can use something like the Loom class of WhyDoIDoIt which allows you to easily schedule a method / lambda expression / delegate on a seperate thread and also provides a way to schedule a method / lambda expression / delegate back on the main thread. So you can simply do something like:

 Loom.RunAsync(()=>{
     // this will be executed on a seperate thread
     
     // Run your blocking code here

     // when done and you have your result you can schedule the following
     // lambda back on the main thread:
     Loom.QueueOnMainThread(()=>{
         // this will be executed on the main thread
         onAddressDiscovered(address);
     });
 });


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

137 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 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Coroutine Death on Scene Change 3 Answers

How to handle a slow function from a dll 1 Answer

Return value from coroutine to non monobehaviour 1 Answer

Instantiating many objects during update lags 1 Answer

Call long running AI function without tying up game loop? 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