async Task.Run lambda 表达式在 Android 上使 Unity AR 应用程序崩溃,但在 iOS 上运行良好
Posted
技术标签:
【中文标题】async Task.Run lambda 表达式在 Android 上使 Unity AR 应用程序崩溃,但在 iOS 上运行良好【英文标题】:async Task.Run lambda expression crashes Unity AR app on android but works fine on iOS 【发布时间】:2021-09-23 23:34:16 【问题描述】:我正在使用 Unity 2020.3.4 和 ARCore 4.0.12 以及 Azure Spatial Anchors 2.8.1 创建一个应用程序。它是适用于 android 和 ios 的跨平台应用程序。首先,我创建了一个 iOS 版本,在其中创建了一个 Task.Run(async() => ); void 函数中的 lambda 表达式,以便能够调用 Azure 空间锚的异步函数。我是这样做的,因为这个函数是在按下 Unity 按钮时调用的,它不需要异步任务,但它确实需要 void。这在 iOS 设备上运行良好,但在我在 Android 设备上测试后,此代码使应用程序崩溃。
//Called on Unity UI button press, works fine on IOS, but crashes the app on Android
public void BROKENStartLookingForAnchor()
Task.Run(async () =>
if (!hasStartedOnce)
await StorageManager.instance.InitializeStorage();
anchorId = await StorageManager.instance.DownloadBlob(blobName);
spatialAnchorManager.SessionStarted += OnSessionStarted;
spatialAnchorManager.AnchorLocated += CloudManager_AnchorLocated;
anchorLocateCriteria = new AnchorLocateCriteria();
if (spatialAnchorManager.Session == null)
await spatialAnchorManager.CreateSessionAsync();
SetAnchorLocateCriteria();
await spatialAnchorManager.StartSessionAsync();
);
一开始很难找出问题所在(我使用 LogCat 进行调试),但是一旦我将代码更改为以下代码,它在 Android 上也能正常工作。
//Called on Unity UI button press, because cannot call async Task from Unity button press
public async void StartLookingForAnchor()
await StartLookingForAnchorAsync();
private async Task StartLookingForAnchorAsync()
if (!hasStartedOnce)
await StorageManager.instance.InitializeStorage();
anchorId = await StorageManager.instance.DownloadBlob(blobName);
spatialAnchorManager.SessionStarted += OnSessionStarted;
spatialAnchorManager.AnchorLocated += CloudManager_AnchorLocated;
anchorLocateCriteria = new AnchorLocateCriteria();
if (spatialAnchorManager.Session == null)
await spatialAnchorManager.CreateSessionAsync();
SetAnchorLocateCriteria();
await spatialAnchorManager.StartSessionAsync();
但是,即使我解决了这个问题,我仍然不确定为什么第一个选项在 Android 上不起作用,以及为什么第二个可以,因为我对异步函数和多线程不是很熟悉。谁能给我解释一下?
【问题讨论】:
【参考方案1】:查看这些问题
https://github.com/Azure/azure-spatial-anchors-samples/issues/230 https://github.com/Azure/azure-spatial-anchors-samples/issues/283
如果您遇到类似错误,请尝试 Vastja 提到的解决方法
【讨论】:
【参考方案2】:Task.Run(async () => ... );
返回一个Task
,在您的第一个版本中没有等待,其中BROKENStartLookingForAnchorAsync()
的返回类型仅为void
。
在您的第二个版本中,等待由async Task StartLookingForAnchorAsync()
返回的Task
(这可以通过具有async void
返回类型的StartLookingForAnchor()
实现)。
我怀疑如果您将第一个版本返回 async void
并将代码设置为 await Task.Run(async () => ... );
,或者只是删除了完全包裹其余代码的 Task.Run()
,那么您的第一个版本也可以工作。
不鼓励使用 C# async documentation、async void
返回类型,但事件处理程序除外,这听起来像是按下 Unity 按钮的用例。
Unity QuickStart tutorials in the Azure Spatial Anchors documentation 可能是用于 Unity + ASA 的模式的良好起点。
【讨论】:
以上是关于async Task.Run lambda 表达式在 Android 上使 Unity AR 应用程序崩溃,但在 iOS 上运行良好的主要内容,如果未能解决你的问题,请参考以下文章
async await task.run xamarin 表单
C# Task.Run() 与 C++ std::async()
Task.Run(()=> DoWorkAsync()) 和 new Thread(async()=> DoWorkAsync()); 的区别