Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用协同程序在Unity中访问SQLite数据库_C#_Sqlite_Unity3d_Yield Return - Fatal编程技术网

C# 使用协同程序在Unity中访问SQLite数据库

C# 使用协同程序在Unity中访问SQLite数据库,c#,sqlite,unity3d,yield-return,C#,Sqlite,Unity3d,Yield Return,我在Unity中创建了一个菜单,它由SQLite DB的结果填充。然而,当我创建菜单时,整个游戏在查询数据库时冻结了片刻 为了解决这个问题,我尝试将菜单的创建和数据填充分开(即,在查询完成之前,菜单只会说“加载”) 我一直在尝试使用收益-回报联合例程来实现这一点,但游戏仍然冻结。下面我有一些伪代码说明我在做什么 void createMenu () { // code to create menu... StartCoroutine(getData()); } IEnu

我在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 

}
void createMenu(){
//创建菜单的代码。。。
start例程(getData());
}
IEnumerator getData(){
List sqlResults=Database.query(“从表中选择*);
收益返回空;
updateMenu();
}
void updateMenu(){
//用sql数据结果替换“加载”字符串
}

我是以错误的方式进行的,还是我错误地使用了协同程序

因此,这里的问题是,您正在与服务器同步,而不是异步,这将使您等待连接或查询(如果它给您提供了错误或错误的查询,您将等待httprequest或db request超时)。
尝试使用异步函数而不是枚举器,或者使用带有异步函数调用的枚举器,这将使您在检索信息时出现在菜单上。

看起来数据库操作正在阻止主线程。使用
ThreadPool.QueueUserWorkItem
函数在新线程中运行它。完成后,使用post中的
UnityThread.executeInUpdate
函数调用
updateNu()
函数。您需要从post获取
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();
    });
}

是的,将此代码放在一个协同程序中不会改变任何东西。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();
}
IEnumerator获取数据(){
列出结果;
var thread=new System.Threading.thread(()=>{
sqlResults=Database.query(“从表中选择*);
};
thread.Start();
while(thread.IsAlive){
收益返回空;
}
updateMenu();
}

但它是一个SQLite数据库。没有涉及服务器?它只是访问一个数据库文件。你有关于如何编写异步函数的示例的链接吗?Unity文档是无用的,检查一下,你是说用Unity无法本机实现这一点?你的评论没有意义。这个答案是“本机”实现的因此,从
createMenu
函数调用
runQuery(“从表中选择*);
。它不应该阻止或冻结unity。如果不是,那么问题出在
updateMenu()中
函数,你也应该发布它。我的意思是,我必须包含那个家伙的整个UnityThread类才能让它工作。它足够长,可以成为一个外部DLL。答案应该可以工作,但它做的事情和我做的一样,只是它的性能不如我的答案,因为它每次我都在创建新的
线程不要使用
ThreadPool
。另外,它不像我制作的
UnityThread
脚本那样是线程安全的,但它应该可以工作。
UnityThread
是我写的,所以你不必写自己的。它使在Unity中使用线程更容易和安全。就是这样。如果你不想使用它,你可以编写自己的包装器。它的主要目标是简化Unity中线程的使用。您的答案也解决了这个问题,但是@Programmer得到了他们的第一个答案:)
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();
}