【问题标题】:Getting null as a results when using Tasks使用任务时获得 null 作为结果
【发布时间】:2020-02-21 09:22:21
【问题描述】:

我正在尝试在循环中调用异步函数来生成对象。它不像我预期的那样工作。字典给出了关于多次添加相同项目的错误。我不能使整个函数异步。代码如下:

public Dictionary_String_Prop GeneratePlaceables(List<PropData> props, Prop parent = null)
{
    Dictionary_String_Prop temp = new Dictionary_String_Prop ();
    if(props == null)
    {
        Debugger.Log("PropdataList Empty: Returning Empty Dictionary");
        return temp;
    }
    for (int i = 0; i < props.Count; i++)
    {
        var result = GameModeGame.Get().placeableDB[props[i].dataID].Prefab;
        PropData propData = props[i];
        result.InstantiateAsync(props[i].sTransform.Position(), props[i].sTransform.Rotation()).Completed += a => 
        { 
            Placeable p = a.Result.GetComponent<Placeable>();

            p.uniqueID = propData.uniqueID;
            p.State = propData.state;
            p.InitData();
            if(parent)
                p.SetParent(parent);
            else
                p.transform.SetParent(manager.transform);

            p.transform.localScale = propData.sTransform.Scale();

            p.children = GeneratePlaceables(propData.placeables, p);

            temp.DebugLog();
            temp.Add(p.uniqueID, p);
            manager.allProps.Add(p.uniqueID, p);
        };
    }
    return temp;
}

我还尝试将所有实例化任务保存到一个数组中,然后使用 Task.WaitAll() 等待线程完成然后从函数返回,但它也会抛出错误。

问题:- 如何在退出循环之前异步实例化每个对象?

【问题讨论】:

  • Dictionary_String_Prop 是什么?它是一个线程安全的字典吗? (如ConcurrentDictionary)。 InstantiateAsync 的原型是什么?
  • 这是一个序列化的字典。我不确定线程​​安全。也许我应该用普通字典测试。
  • 如果InstantiateAsync 真的是异步的,那么您不会在函数存在之前等待这些任务完成。整个函数真的需要异步吗?
  • 它来自 Unity 的 API。 public static AsyncOperationHandle&lt;GameObject&gt; InstantiateAsync(object key, Transform parent = null, bool instantiateInWorldSpace = false, bool trackHandle = true) 这是我从那里复制的整个语法。这是页面的link

标签: c# unity3d async-await task


【解决方案1】:

您可能需要查看 c# 的 async/await 文档:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

每个async 方法在您的代码中都需要一个匹配的await,您不需要等待任务的结果,所以......

result.InstantiateAsync(.....

需要等待:

await result.InstantiateAsync(.....

但这会产生你需要使你的函数async

public Dictionary_String_Prop GeneratePlaceables(List<PropData> props, Prop parent = null)

需要更改为:

public async Task<Dictionary_String_Prop> GeneratePlaceables(List<PropData> props, Prop parent = null)

任何调用GeneratePlaceables 的方法也需要awaitWhy use Async/await all the way down


如果您不能对函数进行更改,还有另一种方法可以让您同步等待结果:

Foo foo = GetFooAsync(...).GetAwaiter().GetResult();

所以:

result.InstantiateAsync(....).GetAwaiter().GetResult();

这不需要更改功能等...

希望对你有帮助

【讨论】:

  • 我知道我可以使用 async 和 await 但由于某些原因我无法更改该功能。没有异步等待还有其他方法吗?
  • 更新了我的答案以包含一种无需使用 await 即可获得结果的方法
猜你喜欢
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 2015-05-16
相关资源
最近更新 更多