简体   繁体   English

统一执行sqlite操作时,场景冻结了几秒钟

[英]Scene freeze few seconds when doing sqlite operations in unity

In my application have a feature like 'Sync' data, In sync operation get the data from server and stored in local sqlite database and push local data to server. 在我的应用程序中,具有“同步”数据之类的功能,在同步操作中,从服务器获取数据并存储在本地sqlite数据库中,然后将本地数据推送到服务器。 When user click on sync, scene freeze up to completed the push and pull operations. 当用户单击同步时,场景将冻结以完成推和拉操作。 How can I get out of this problem. 我如何摆脱这个问题。 I have tried like using separate thread for doing database operations but I am getting exception like persistance database operations work on main thread only. 我试图像使用单独的线程来执行数据库操作一样,但是我遇到了类似持久性数据库操作仅在主线程上起作用的异常。 How can I do sync operation without freeze the screen. 如何在不冻结屏幕的情况下进行同步操作。 Please suggest any idea, Thanks in advance. 请提出任何想法,谢谢。

Here is the sample code I have tried 这是我尝试过的示例代码

 var thread = new System.Threading.Thread(() =>
 {
     //do sqlite operations
 });

 thread.start();

You should be doing expensive queries in another Thread. 您应该在另一个线程中执行昂贵的查询。 Once the query returns, you can use the result in the main Thread . 查询返回后,您可以在主Thread使用结果。 I noticed you made attempt to use Thread but you're getting new error: 我注意到您尝试使用Thread但遇到了新错误:

get_persistentDataPath can only be called from the main thread. 只能从主线程调用get_persistentDataPath。

This is because you're using Application.persistentDataPath in another Thread . 这是因为您在另一个Thread使用Application.persistentDataPath You cannot use most Unity API in another Thread and Application.persistentDataPath is one of them. 不能在另一个Thread使用大多数Unity API, Application.persistentDataPath是其中之一。 This is a simple fix. 这是一个简单的修复。 There is no reason to use Application.persistentDataPath in another Thread. 没有理由在另一个线程中使用Application.persistentDataPath Get the value of Application.persistentDataPath and store in in a global string variable then use that global variable in the new Thread. 获取Application.persistentDataPath的值并存储在全局string变量中,然后在新的Thread中使用该全局变量。

For example: 例如:

Don't do this ( this is what you're currently doing): 不要执行此操作 (这是您当前正在执行的操作):

void Start()
{
    //This Start function is the main Thread (Unity's Thread)

    var thread = new System.Threading.Thread(() =>
    {
        //This is another Thread created by you

        //DO NOT DO THIS(Don't use Unity API in another Thread)
        string dbPath = Application.persistentDataPath;

        //do sqlite operations
    });
    thread.Start();
}

Do this instead (Get the variable of Application.persistentDataPath in the main thread before then use the stored value): 而是这样做 (在主线程中获取Application.persistentDataPath的变量,然后使用存储的值):

void Start()
{
    //This Start function is the main Thread (Unity's Thread)

    //Get path in the Main Thread
    string dbPath = Application.persistentDataPath;

    var thread = new System.Threading.Thread(() =>
    {
        //This is another Thread created by you

        //Use the path result here


        //do sqlite operations
    });
    thread.Start();
}

Finally, if you really need to use many other Unity API other than Application.persistentDataPath or for example, update the UI Text component with result from the database, you can use my UnityThread plugin which simplifies that. 最后,如果您确实需要使用Application.persistentDataPath以外的其他许多Unity API,或者例如使用数据库中的结果更新UI Text组件,则可以使用简化了的UnityThread插件。

public Text yourTextComponent;

void Start()
{
    UnityThread.initUnityThread();
    //This Start function is the main Thread (Unity's Thread)

    //Get path in the Main Thread
    string dbPath = Application.persistentDataPath;

    var thread = new System.Threading.Thread(() =>
    {
        //This is another Thread created by you

        //do sqlite operations

        //Show result on UI
        UnityThread.executeInUpdate(() =>
        {
            yourTextComponent.text = queryResult;
        });
    });
    thread.Start();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM