统一更新来自不同线程的变量
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
关键字可以完成此操作。
由于 d
在 ParsePayload
函数中更新并在 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;
}
}
}
我开始学习一些统一性,我有一个关于多线程的快速问题。
我有一个 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
关键字可以完成此操作。
由于 d
在 ParsePayload
函数中更新并在 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;
}
}
}