Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Working with threads: "can only be called from the main thread"

Discussion in 'Scripting' started by gambr, Jan 23, 2018.

  1. gambr

    gambr

    Joined:
    Oct 13, 2017
    Posts:
    109
    Dear All,
    I'm a c++ programmer new to Unity and C#.
    I implemented a Thread in a class that inherits from MonoBehaviour. In the Awake() method I get a specific GameObject from the scene and store it in a class member, then I start a server on a Thread.
    Unexpectedly when the server callback is called the GameObject variable seems corrupted.

    Here is a code snippet:

    Code (CSharp):
    1. public class ThriftService : MonoBehaviour, unity3Dservice.Iface
    2. {
    3.    private Thread workerThread = null;
    4.    private GameObject fpsGameObject = null;
    5.  
    6.    public WidgetSetupData GetWidgetConfig(WGT_TYPE wgt)
    7.    {
    8.       WidgetSetupData data = new WidgetSetupData();
    9.       data.Position = new WGT_Position();
    10.       data.Position.X = fpsRectTransform.anchoredPosition.x;
    11.       return data;
    12.    }
    13.  
    14.    void Awake() {
    15.       fpsGameObject = GameObject.FindGameObjectsWithTag("FpsDisplayCanvas")[0];
    16.       startServerThread();
    17.    }
    18.  
    19.    void startServerThread() {
    20.       workerThread = new Thread(runServer);
    21.       try {
    22.          workerThread.Start();
    23.       } catch (Exception e) {
    24.          Debug.LogError(e.StackTrace);
    25.       }
    26.    }
    27.  
    28.    void runServer() {
    29.       unity3Dservice.Processor processor = new unity3Dservice.Processor(this);
    30.       TServerTransport serverTransport = new TServerSocket(unity3d_serviceConstants.unity3Dservice_port);
    31.       server = new TSimpleServer(processor, serverTransport);
    32.       server.Serve();
    33.    }
    34. }
    GetWidgetConfig is the callback where "fpsRectTransform" is not a valid object.
    On the Unity Console I get the error:

    "INTERNAL_get_anchoredPosition can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
    UnityEngine.RectTransform:get_anchoredPosition()
    ThriftService:GetWidgetConfig(WGT_TYPE) (at Assets/Scripting/ThriftService.cs:43)"

    Can anybody explain me this behaviour and a suggested solution?

    Best regards,
    Gianni
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    You can't access the Unity API from any thread outside of the main execution thread of Unity.

    If you need data from Unity for a thread, you'll need to gather said information as a token and pass it along to the thread.

    Otherwise various people have created various tools that facilitate syncing back to the Unity thread to gather/set information from threads. But note this increase overhead as join the main thread and then leave it again.
     
  3. gambr

    gambr

    Joined:
    Oct 13, 2017
    Posts:
    109
    I can't believe it!!! I thought Unity was out for years and it is still not thread safe?? That's a big limitation. Wake up Unity team!
     
  4. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148



    soon
     
  5. bigChris

    bigChris

    Joined:
    Jul 5, 2017
    Posts:
    8
  6. Lenny991

    Lenny991

    Joined:
    Dec 27, 2020
    Posts:
    4
    So, how would i fix that? I have the same issue but just with GetName. I have no idea what threads are and i am not working with them so i don't know why this happens.
     
  7. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,000
    Greviouss and yusuf_isik like this.