1

I am starting to learn some unity and I have a quick question in regards to multithreading.

I have a class which contains an instance of a datamodel class. The primary function of the class is the fetch a remote resource asynchronously and update the datamodel class. Then in the update function the datamodel class is read out and written to some text in a gameobject.

Anyway I am worrying that it could cause some issues related to multithreading since my async updating of the class could run at the same time as the update function causing a race condition. Do I have to wrap access to the class in a mutex?

class Data {
    public int Number { get; set; }
    public string Name { get; set; }
}

class Network : MonoBehaviour {
    private Data d;

    public void Start() {
        // setting up handler to async fetch data and call provided callback
        Networking.GetData(s => ParsePayload(s));
    }

    private void ParsePayload(string payload) {
        d = JsonConvert.DeserializeObject<Data>(payload);
    }

    public void Update() {
        var label = GameObject.Find("textObject").GetComponent<Text>();
        label.Text = d.Name;
    }
}

So am I right in this or does unity handle this by itself?

thx for any advice!

  • Without posting your code, any answer you get will likely not be useful to you. at-least, try to show what you are doing – Programmer Nov 25 '16 at 20:03
  • @Programmer updated my question... –  Nov 25 '16 at 20:14
  • Where are you updating the class and where is the Thread code. This is missing. If you have both of these, somebody here can help you answer this. – Programmer Nov 25 '16 at 20:29
  • @programmer it isn't missing.... ParsePayload() –  Nov 25 '16 at 20:31
  • You only answered part the missing question. `ParsePayload` is passed into another `Thread` for callback and that `Thread` will call it when result is available. Now, where is the Thread code that calls `ParsePayload`? Does it access `Data d` anywhere? – Programmer Nov 25 '16 at 20:37
  • @Programmer `Data d` isn't accessed anywhere outside of the class. But ParsePayload still runs in a different thread. –  Nov 25 '16 at 20:42
  • @JohnSmith, there is almost *no reason* to ever use separate threads in Unity. You should almost certainly forget about this. (Regarding grabbing something from the www, it's totally trivial, just google.) – Fattie Nov 26 '16 at 13:58
  • @JoeBlow Really? all solution either use coroutines which is basically multithreading or try to force it into a generator which is a bad fit, since you still will have blocking calls. –  Nov 26 '16 at 21:38
  • just use www, it goes to another thread for you. all you're doing is getting something from the web - it's nothing. one line of code – Fattie Nov 27 '16 at 00:48
  • @JohnSmith There is a new solution for this. Ignore the one I left even though it works. Look at the duplicate. – Programmer Dec 26 '16 at 19:09

1 Answers1

2

So am I right in this or does unity handle this by itself?

You are right in this. It could cause some problems and Unity does not handle this by itself. You are responsible to making sure that only one Thread can access d variable at a time. There are several ways of this but using the lock keyword can accompilsh this.

Since d is updated in the ParsePayload function and accessed in the Update function, you have to use the lock keyword in both functions.

Another unrelated problem is the GameObject.Find("textObject"). This should be done in the Start() function and saved to a variable. Don't do that in the Update function each frame.

class Network : MonoBehaviour
{
    private Data d;
    Text label;

    private System.Object threadLocker = new System.Object();

    public void Start()
    {
        label = GameObject.Find("textObject").GetComponent<Text>();

        // setting up handler to async fetch data and call provided callback
        Networking.GetData(s => ParsePayload(s));
    }

    private void ParsePayload(string payload)
    {
        lock (threadLocker)
        {
            d = JsonConvert.DeserializeObject<Data>(payload);
        }
    }

    public void Update()
    {
        lock (threadLocker)
        {
            label.text = d.Name;
        }
    }
}
Programmer
  • 121,791
  • 22
  • 236
  • 328