2016-11-25 3 views
0

Я начинаю изучать некоторое единство, и у меня есть быстрый вопрос в отношении многопоточности.Единство Обновление переменной из другой темы

У меня есть класс, который содержит экземпляр класса datamodel. Основной функцией класса является асинхронное извлечение удаленного ресурса и обновление класса datamodel. Затем в функции обновления класс datamodel считывается и записывается в некоторый текст в игровом объекте.

В любом случае, я беспокоюсь, что это может вызвать некоторые проблемы, связанные с многопоточным чтением, так как обновление async класса может выполняться одновременно с функцией обновления, вызывающей условие гонки. Нужно ли мне переносить доступ к классу в мьютексе?

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

Так я прав в этом или единство справляется с этим сам по себе?

thx для любых советов!

+0

Если вы не разместили свой код, любой ответ, который вы получите, скорее всего, не пригодится вам. по крайней мере, попробуйте показать, что вы делаете – Programmer

+0

@Programmer обновил мой вопрос ... –

+0

Где вы обновляете класс и где находится код Thread. Это отсутствует. Если у вас есть оба, кто-то здесь может помочь вам ответить на этот вопрос. – Programmer

ответ

1

Так я прав в этом или единство справляется с этим сам по себе?

Вы правы в этом. Это может вызвать некоторые проблемы, и 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; 
     } 
    } 
} 
Смежные вопросы