Firebase 使任务仅在主线程上执行,导致 Unity 冻结
Posted
技术标签:
【中文标题】Firebase 使任务仅在主线程上执行,导致 Unity 冻结【英文标题】:Firebase makes Tasks execute only on main thread causing Unity to freeze 【发布时间】:2017-06-17 00:03:27 【问题描述】:我对@987654321@ 的 firebase 1.1.0 有疑问。
一旦我通过FirebaseApp.DefaultInstance.SetEditorDatabaseUrl( myurl )
激活了firebase,所有不是由firebase 生成的Tasks 都会在主线程上执行。
所以我可以很好地检索和发布数据到 firebase,甚至可以在任务中处理它。它们在单独的线程上运行,我在调试时看到了。但是,当我在某些 MonoBehaviour 的 Start
方法中使用 Task.Run( MyComputingFunction )
时,Unity 会挂起。假设这个函数只是从0
计数到999999
所以它不是一个锁定 问题。由于任务在主线程上执行,计算时 Unity 会冻结。如果我将 firebase 激活注释掉,我的 task 将在单独的 thread 中运行并且不会冻结 Unity。
请帮忙。
这是一个最小的工作示例。将其附加到游戏对象并观察并行运行的任务。取消注释指出的行,任务将按线性顺序执行。
using UnityEngine;
using System;
using System.Threading.Tasks;
using Firebase.Unity.Editor;
using Firebase.Database;
public class NetworkController : MonoBehaviour
public static DatabaseReference @ref;
void Start()
// Uncomment line below
//InitializeDatabase();
TestStuff();
private void TestStuff()
Task.Run( Counter(1) );
Task.Run( Counter(2) );
Task.Run( Counter(3) );
private Action Counter( int i )
return delegate
int a = 0;
while ( a + 10 < 900000 )
a++;
if ( a % 5000 == 0 )
Debug.Log( a + i);
;
private void InitializeDatabase()
Firebase.FirebaseApp.DefaultInstance.SetEditorDatabaseUrl( "https://dinosaur-facts.firebaseio.com/" );
@ref = FirebaseDatabase.DefaultInstance.RootReference;
【问题讨论】:
你能发布你的代码吗? @MichaelDotKnox 我已经更新了我的帖子。 【参考方案1】:我是一名 Firebase 工程师,刚刚查看了您的帖子。很抱歉你碰到了这个。
这是我们所依赖的 UnityTask 库中的一个错误。发生的事情是任务库误用 SynchronizationContext.Current(设置时)作为启动任务的工具。 Task.Run 应该始终使用线程池,而不是 SynchronizationContext.Current。 SynchronizationContext.Current 旨在用于编组来自其他线程的调用。
我会在我们这边调查解决这个问题。在此期间,我确实有一个解决方法供您使用。
TaskFactory factory = new TaskFactory(new TaskScheduler(null)); //null = threadpool.
factory.StartNew(() => myFunction());
【讨论】:
此修复的 PR 是 here: 在此修复获得批准之前,您需要使用解决方法。 没问题。非常感谢您的解决方法。 Firebase 很棒,我很高兴您将它集成到 Unity 中。 还没修好? @BenjaminWulfe 问题现在是使用 TaskScheduler(null) 从 TaskFactory 调用 firebase。但是我们不能在该任务函数中调用统一函数。因为必须从unity自己的线程调用unity函数 这不是 firebase 问题。这是一个关于如何使用微软的任务库的问题。如果你需要在某个线程上运行,你应该使用特定的任务调度器。【参考方案2】:(我是 firebase C++ / Unity 团队的工程师。)
我相信我们在过去的版本中修复了这个问题。 https://firebase.google.com/support/release-notes/unity#4.0.3
最近我们刚刚发布了 4.3.0,据报道,我们对线程和任务进行了多项改进和修复。
【讨论】:
以上是关于Firebase 使任务仅在主线程上执行,导致 Unity 冻结的主要内容,如果未能解决你的问题,请参考以下文章