- Home /
Can I use coroutine to replicate .WaitOne() and .Set() behaviour?
Hi all,
I'm trying to bring across some C# code into Unity C# Scripts. The original code enables communication between a client and server (both located on the same machine) - real-time data comes through from the server, which can then be accessed via the client.
When attempting to move the code over, I found that when entering Playmode on Unity, it would always freeze when .WaitOne() or .Set() was invoked. I researched online and found that there are issues with working with threads in Unity3D, and that the best alternative is to work with coroutines to simulate aspects of thread behaviour.
Does anyone know if the functions .WaitOne() and .Set() is possible to replicate using coroutines? I know that doing yield return new WaitForSeconds(1.0f) can pause the execution of the coroutine function until the time specified, but would this cause issues with retrieving real-time data?
The way the original C# code is set out, is that you 'subscribe' to a data stream, and it continuously sends the request for the data and retrieves the data requested until you disconnect from the client and server. Setting an estimated time for how long you think the function should be paused for, doesn't feel reliable to me, as it might still be trying to send over some data but you haven't provided enough time for it to complete the process.
Any comments are welcome!
Thanks
Answer by Bunny83 · Mar 03, 2017 at 08:06 PM
Yes, it's possible to implement some sort of wait handles for coroutines. However they would work a bit different. Normal wait handles would block a thread until they get signaled. When signaled the thread would continue immediately. This of course isn't possible with coroutines. If a coroutine would wait for a signal it would continue the next time the coroutine scheduler processes the coroutine. This happens only once per frame. So if another thread signals the wait handle the coroutine could take up to one frame until it is actually resumed.
It highly depends on your actual usecase and code if it actually makes sense to use such a construct. Usually for socket io operations it's easier to use threads and a synchronised Queue to transfer received data over to the main thread. That way the threads don't have to wait for each other, only at the time when data is queued / dequeued but that shouldn't take much time.
There are no real problems with threads in Unity. Just keep in mind that pretty much everything of the Unity API can only be accessed from the main thread.
Thank you for the response! It's helped clear up some confusion I had :)
hi..I used threads to connect to socket but i faced this problem that i cant use unity api in thread... can u provide me an example how to solve this?
@aglida1370 You should post a new question for that, explaining what your problem actually is (being unable to use the Unity API off the main thread is not in itself a problem - you just need to remember it and have your networking thread steer clear of that API - so in your question you should explain why you're finding that difficult).
Are you still working on the same thing? You posted this comment about a year ago. Though for sockets you wouldn't use something like the Loom class or another TaskExecuter. Ins$$anonymous$$d you would directly pass the received data through the queue.
However as Bonfire said, ask a seperate question and show your code what you have so far. There is no one-fits-it-all solution when it comes to multithreading. Usually the socket thread will pre-process the raw data, do some parsing and prepare a nice "message" which is queued in a thread safe queue. In Update (or a coroutine) you can then dequeue those messages from the queue and process them on the main thread. For sending messages you would do the same thing in reverse (with a seperate queue of course).
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Game server crashes in release and debug build but not in editor (GetThreadContext failed) 0 Answers
Connect to non-unity server with LLAPI 0 Answers
Problem with GetNetworkTime 0 Answers
tcp socket error message (C#) 1 Answer