【问题标题】:Unity C# Firebase can't modify/access list variable in task scopeUnity C# Firebase 无法在任务范围内修改/访问列表变量
【发布时间】:2020-08-22 06:49:40
【问题描述】:

我无法访问/编辑 getvalueasync 任务中的列表变量,任何尝试修改或读取列表“ShopItems”的代码都不会返回任何内容并阻止任何进一步的代码在同一范围内运行,不会返回任何错误在控制台中。 “ItemsLoaded” int 变量没有问题。

public static void IsItemPurchased(string item)
    {
        Debug.Log(ShopManager.ShopItems[0]); // This works
        FirebaseDatabase.DefaultInstance.GetReference("/Shop/" + item + "/").GetValueAsync().ContinueWith(task =>
        {
            if (task.IsFaulted || task.IsCanceled)
            {
                Debug.LogError("Database: Failed to check item status - " + task.Exception);
            }
            else if (task.IsCompleted)
            {
                bool isPurchased;
                if (task.Result.Value == null)
                    isPurchased = false;
                else
                    isPurchased = (bool)task.Result.Value;
                Debug.Log(ShopManager.ShopItems[0]); // Does not work
                Debug.Log(ShopManager.ItemsLoaded); // This works
                ShopManager.ShopItems.Where(i => i.gameObject.name == item).FirstOrDefault().Purchased = isPurchased; // Variable does not update
                ShopManager.ItemsLoaded++;
            }
        });
    }

【问题讨论】:

    标签: c# firebase unity3d


    【解决方案1】:

    需要注意的事项:

    • 根据GetValueAsync 的结果更改游戏状态通常很危险。有关更多详细信息,请参阅this SO answer(这是一个 Android 答案,但也应该适用于 iOS),但总体思路是调用 GetValueAsync 通常会从服务器请求数据并返回当前缓存的任何数据(所以你会错过如果您不同步,请查看最新数据)。最好收听ValueChanged 事件并以这种方式更新商店商品。
    // important, cache this to cleanup later.
    var shopReference = FirebaseDatabase.DefaultInstance.GetReference("/Shop/");
    
    // your  have a Dictionary (or an Array if your items are more or less linear integers) from which you can get the value of all your items and update your shop accordingly. You could also listen per item in your shop.
    shopReference.ValueChanged += HandleShopUpdated;
    
    // important, do this in your OnDestroy. These are C# events with no knowledge of Unity's C# lifecycle
    shopReference.ValueChanged -= HandleShopUpdated;
    
    • 您使用的是ContinueWith 而不是ContinueWithOnMainThread。根据您的游戏,如果这些调用中的任何一个涉及到 UnityEngine 命名空间中的某些内容(例如 gameObject.name),它可能会因位于错误的线程上而引发异常。 ContinueWithOnMainThreadContinueWith 的替代品,因此请考虑使用它。
    • 一般注意事项,因为您使用的是ContinueWith 而不是ContinueWithOnMainThread(即:如果您遵循我之前的建议,您可能会忽略这一点)。由于ItemsLoaded 是从任务访问的,因此请确保将其标记为volatile。如果多个线程同时在同一块内存上工作,您可能会错过增量操作(这不太可能,但也很难捕捉)。

    【讨论】:

      猜你喜欢
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      相关资源
      最近更新 更多