统一更新来自不同线程的变量

unity updating variable from different thread

我开始学习一些统一性,我有一个关于多线程的快速问题。

我有一个 class,其中包含一个数据模型实例 class。 class 的主要功能是异步获取远程资源并更新数据模型 class。然后在更新函数中,数据模型 class 被读出并写入游戏对象中的一些文本。

无论如何,我担心它可能会导致一些与多线程相关的问题,因为我对 class 的异步更新可能 运行 同时与更新函数导致竞争条件。我是否必须将对 class 的访问权包装在互斥体中?

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;
    }
}

我说得对还是 unity 自己处理这个问题?

感谢任何建议!

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

你说得对。它可能会导致一些问题,Unity 不会 自行处理。您有责任确保一次只有一个线程可以访问 d 变量。有几种方法,但使用 lock 关键字可以完成此操作。

由于 dParsePayload 函数中更新并在 Update 函数中访问,因此您必须在两个函数中使用 lock 关键字。

另一个不相关的问题是GameObject.Find("textObject")。这应该在 Start() 函数中完成并保存到一个变量中。不要在每一帧的更新函数中这样做。

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;
        }
    }
}