Сцена останавливается на несколько секунд при выполнении операций sqlite в единстве - PullRequest
0 голосов
/ 29 августа 2018

В моем приложении есть такая функция, как «Синхронизация» данных. В режиме синхронизации получают данные с сервера и сохраняют их в локальной базе данных sqlite и отправляют локальные данные на сервер. Когда пользователь нажимает на синхронизацию, сцена останавливается, чтобы завершить операции push и pull. Как я могу выйти из этой проблемы. Я пытался использовать отдельный поток для выполнения операций с базой данных, но получаю исключение, так как операции с базой данных персистентности работают только в основном потоке. Как я могу сделать синхронизацию без остановки экрана. Пожалуйста, предложите любую идею, спасибо заранее.

Вот пример кода, который я пробовал

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

 thread.start();

1 Ответ

0 голосов
/ 29 августа 2018

Вы должны делать дорогие запросы в другой теме. Как только запрос вернется, вы можете использовать результат в основном Thread. Я заметил, что вы попытались использовать Thread, но вы получаете новую ошибку:

get_persistentDataPath может вызываться только из основного потока.

Это потому, что вы используете Application.persistentDataPath в другом Thread. Вы не можете использовать большинство API Unity в другом Thread, и Application.persistentDataPath является одним из них. Это простое исправление. Нет смысла использовать Application.persistentDataPath в другой теме. Получите значение Application.persistentDataPath и сохраните в глобальной переменной string, затем используйте эту глобальную переменную в новом потоке.

Например:

Не делайте этого (это то, что вы сейчас делаете):

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();
}

Сделайте это вместо (получите переменную 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();
}

Наконец, если вам действительно нужно использовать множество других API Unity, отличных от Application.persistentDataPath или, например, обновить текстовый компонент пользовательского интерфейса с помощью результата из базы данных, вы можете использовать мой плагин 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...