- Home /
Unity Asynchronous Socket Client - Threading Problem
Hello, I am trying to make a simple asynchronous socket client and communication goes very well. The problem is I cannot do much with the received information, as it is not processed in the main thread (I am getting this error: "get_isActiveAndEnabled can only be called from the main thread.").
Is there any simple way how to call the main thread or even simpler way how to do solve this issue?
public Text GameState;
private void ReceiveCallback(IAsyncResult AR)
{
//Check how much bytes are recieved and call EndRecieve to finalize handshake
int recieved = _clientSocket.EndReceive(AR);
if(recieved <= 0)
return;
//Copy the recieved data into new buffer , to avoid null bytes
byte[] recData = new byte[recieved];
Buffer.BlockCopy(_recieveBuffer,0,recData,0,recieved);
//Process data here the way you want , all your bytes will be stored in recData
string incomingMsg = "Received: " + Encoding.ASCII.GetString(recData);
Debug.Log(incomingMsg);
//THIS DOES NOT WORK
GameState.text = incomingMsg;
//Start receiving again
_clientSocket.BeginReceive(_recieveBuffer,0,_recieveBuffer.Length,SocketFlags.None,new AsyncCallback(ReceiveCallback),null);
}
Watch the line: GameState.text = incomingMsg;
I am trying to set UI.Text field's value to no avail.
I came with exactly the same problem... I tried to use loom to call the main thread but nothing changes,I'm afraid is does not matter with "main thread" much,maybe something else unpredictable causes this issue.
The Loom class (that one WhyDoIDoIt wrote) should work fine. Your "task" would be queued in an event queue and actually run from the Update callback of the Loom class. You most likely use the class in a wrong way? Are you sure that the error is on the line you pointed out?
"get_isActiveAndEnabled" belongs to Behaviour.isActiveAndEnabled. The error you get will be thrown whenever you try to read "isActiveAndEnabled" from another thread. Unity has implemented a thread check in most API functions and will throw an error if you try to execute any of those functions from another thread.
It's possible that inside the Text.text
setter Unity checks "isActiveAndEnabled" internally and that's where the error might be thrown, but you should check other places in your code.
$$anonymous$$eep in $$anonymous$$d that you can't read isActiveAndEnabled or any other property from Unity components inside class constructors or fieldinitializer of $$anonymous$$onoBehaviour classes. The creation of $$anonymous$$onoBehaviour classes is handled by Unity's seperate loading thread internally.
Thank you very much!!! I did as you told me and succeeded. I did try to change a unity object's value in the socket's thread which causes this issue. The one who asked this question make the same mistake as me. He used "GameState.text = inco$$anonymous$$g$$anonymous$$sg;" that tries to change a unity object's value in the socket's thread.
Answer by zarch · Apr 30, 2016 at 06:36 PM
Well I do this already and I made a tasker which was improved a little in this thread http://answers.unity3d.com/questions/1039283/multi-threading-safely.html
Answer by kiyotoki · May 01, 2016 at 04:39 PM
As Bunny83 said,"Keep in mind that you can't read isActiveAndEnabled or any other property from Unity components inside class constructors or fieldinitializer of MonoBehaviour classes. "
You cannot try to change a unity object's value in your socket's thread. I made this mistake just as you and got the same error code.
You can try to claim a static variable in the MonoBehaviour class,set incomingMsg to this variable and then change the unity object's value,which in your conditon is "GameState.text",to the variable through a MonoBehaviour method such as Update or something else.
Your answer
Follow this Question
Related Questions
Asynchronous socket hangs intermittently on iOS 1 Answer
Game server crashes in release and debug build but not in editor (GetThreadContext failed) 0 Answers
Can I use coroutine to replicate .WaitOne() and .Set() behaviour? 1 Answer
UDP Sockets for networking, getting overloaded?? 0 Answers
LoadLevel Async 2 Answers