使用协程访问Unity中的SQLite数据库

时间:2017-09-29 11:29:11

标签: c# sqlite unity3d yield-return

我在Unity中创建了一个菜单,该菜单由SQLite DB的结果填充。但是当我创建菜单时,整个游戏会在查询数据库时冻结片刻。

为了解决这个问题,我试图将菜单的创建与数据填充分开(即菜单只会说"加载"直到查询完成)。

我一直试图使用收益回报协同程序来做到这一点,但游戏仍在冻结。下面我有一些伪代码说明我在做什么......

void createMenu () {

    // code to create menu... 

    StartCoroutine(getData());

}

IEnumerator getData () {

    List<string> sqlResults = Database.query("SELECT * FROM table");

    yield return null;

    updateMenu();

}

void updateMenu() {

   // replaces "loading" strings with sql data results 

}

我是以错误的方式解决这个问题,还是我错误地使用了协程?

3 个答案:

答案 0 :(得分:4)

看起来数据库操作阻塞了主线程。使用ThreadPool.QueueUserWorkItem函数在新线程中运行它。完成后,使用this帖子中的UnityThread.executeInUpdate功能调用updateMenu()功能。您需要从this发布UnityThread课程才能使用此解决方案。

void Awake()
{
    UnityThread.initUnityThread();
}

void runQuery(string query)
{
    ThreadPool.QueueUserWorkItem(RunInNewThread, query);
}

private void RunInNewThread(object a)
{
    string query = (string)a;
    List<string> sqlResults = Database.query(query);


    //We are in another Thread. Use executeInUpdate to run in Unity main Thread
    UnityThread.executeInUpdate(() =>
    {
        updateMenu();
    });
}

<强> USAGE

runQuery("SELECT * FROM table");

答案 1 :(得分:1)

是的,将此代码放在协程中,因为您不会更改任何内容。 Unity是单线程的,但是你可以启动一个单独的线程来完成一些工作,只要它们不调用在该线程中执行的任何Unity函数。

试试这个:

IEnumerator getData () {

    List<string> sqlResults;

    var thread = new System.Threading.Thread(() => {
        sqlResults = Database.query("SELECT * FROM table");
    };

    thread.Start();

    while(thread.IsAlive){
        yield return null;
    }

    updateMenu();
}

答案 2 :(得分:0)

所以这里的问题是你正在与服务器同步而不是异步,这将使你等待连接或查询(如果它给你一些错误或它的错误查询你将等到超时httprequest或db请求)。 尝试使用异步函数而不是枚举器,或者使用async fucntion调用的enumator,它可以让你在检索信息时进入菜单。