Перейти к содержанию
Fire Monkey от А до Я
  • 0

Помогите разобраться с потоком


walexw

Вопрос

Опубликовано

rad studio 10 seattle, приложение под андроид
Споткнулся на простой задаче. Нужно, чтобы во время обработки данных (несколько запросов SQL) на экране крутился AniIndicator.
Создал класс domThread на базе потока, в нем одна процедура (код на С++)

void __fastcall domThread::Execute()
{
  frm->aniIndic->Enabled = true; // Запуск индикатора
  frm->aniIndic->Visible = true;
}


В основном коде пишу: (при клике на кнопку)

domThread *aiThread = new domThread(false); // Сразу запустить поток с крутящимся индикатором
Sleep(5000);                                // Это задержка 5 сек. пока заменяет выполнение запросов



По факту получаю следующее, при нажатии кнопки сначала 5 секунд пауза, затем включается индикатор.
Что я делаю неправильно? Разъясните, я впервые с потоками столкнулся.
 

Рекомендуемые сообщения

  • 0
  • Администраторы
Опубликовано

Все просто.

  1. Отрисовка индикатора идёт в главном потоке. Вызывая Sleep в главном потоке, вы лочите главный поток на 5 секунд и как следствие всю отрисовку (Даже если вы выставите раньше Enabled=True). 
  2. С UI компонентами можно работать только в главном потоке, поэтому все вызовы, работающие с компонентами из других потоков нужно завернуть в TThread.Synchronize.
  • 0
  • Модераторы
Опубликовано
14 минут назад, walexw сказал:

rad studio 10 seattle, приложение под андроид
Споткнулся на простой задаче. Нужно, чтобы во время обработки данных (несколько запросов SQL) на экране крутился AniIndicator.
Создал класс domThread на базе потока, в нем одна процедура (код на С++)
void __fastcall domThread::Execute()
{
  frm->aniIndic->Enabled = true; // Запуск индикатора
  frm->aniIndic->Visible = true;
}
В основном коде пишу: (при клике на кнопку)
domThread *aiThread = new domThread(false); // Сразу запустить поток с крутящимся индикатором
Sleep(5000);                                                        // Это задержка 5 сек. пока заменяет выполнение запросов

По факту получаю следующее, при нажатии кнопки сначала 5 секунд пауза, затем включается индикатор.
Что я делаю неправильно? Разъясните, я впервые с потоками столкнулся.
 

нужно делать вот так:

1) использовать компоненты Ярослава

2) анимацию запускаем до потока (в котором выполняются разного рода запросы), по завершению операции в !синхронизации! выключаем анимацию

  • 0
Опубликовано

Сделал все, как здесь посоветовали.
В основном потоке делаю видимым индикатор и включаю его, затем запускаю отдельный поток в который перенес все запросы к БД.
В конце из отдельного потока выключаю индикатор и делаю его невидимым.
Сначала все получилось замечательно, как мне нужно было.
Но со временем заметил, что на устройстве (смартфон, андроид 6) индикатор останавливается, но не исчезает.
Застывший полукруг посреди экрана. Это бывает не всегда. Периодичность не замечена.
Что может быть? Сам функционал остается работать, но вот этот полукруг...
Посоветуйте, как подправить!

  • 0
  • Модераторы
Опубликовано
1 минуту назад, walexw сказал:

Сделал все, как здесь посоветовали.
В основном потоке делаю видимым индикатор и включаю его, затем запускаю отдельный поток в который перенес все запросы к БД.
В конце из отдельного потока выключаю индикатор и делаю его невидимым.
Сначала все получилось замечательно, как мне нужно было.
Но со временем заметил, что на устройстве (смартфон, андроид 6) индикатор останавливается, но не исчезает.
Застывший полукруг посреди экрана. Это бывает не всегда. Периодичность не замечена.
Что может быть? Сам функционал остается работать, но вот этот полукруг...
Посоветуйте, как подправить!

1) надеюсь вы его динамически не создаете? с этим компонентом есть проблемы с динамическим созданием.

2) показывайте код

  • 0
Опубликовано

aIndic - индикатор, лежит на форме, при загрузке приложения ставлю его в середину и делаю Visible=false;

Запускаю индикатор по нажатию кнопки:
aIndic->Enabled  = true;
aIndic->Visible     = true;
Теперь запускаю поток, в котором несколько запросов к БД и их обработка
domThread  *aiThread = new domThread(false);
Больше по кнопке никакого кода нет.

Теперь поток: (FreeOnTerminate = true;)
void __fastcall domThread::Execute()
{
тут те самые запросы и их обработка, в конце:
frm->aIndic->Visible  = false;
frm->aIndic->Enabled  = false;
Terminate();
}

  • 0
  • Модераторы
Опубликовано (изменено)
2 минуты назад, walexw сказал:

aIndic - индикатор, лежит на форме, при загрузке приложения ставлю его в середину и делаю Visible=false;

Запускаю индикатор по нажатию кнопки:
aIndic->Enabled  = true;
aIndic->Visible     = true;
Теперь запускаю поток, в котором несколько запросов к БД и их обработка
domThread  *aiThread = new domThread(false);
Больше по кнопке никакого кода нет.

Теперь поток: (FreeOnTerminate = true;)
void __fastcall domThread::Execute()
{
тут те самые запросы и их обработка, в конце:
frm->aIndic->Visible  = false;
frm->aIndic->Enabled  = false;
Terminate();
}

а где синхронизация?

вы выполняете работу с визуальными компонентами без синхронизации

Изменено пользователем ZuBy
  • 0
Опубликовано
2 часа назад, ZuBy сказал:

а где синхронизация?

вы выполняете работу с визуальными компонентами без синхронизации

void __fastcall domThread::UpdateAnimation()
{
//        Действительно мой код без синхронизации.
//        Я просто не знаю какую команду надо ставить в синхронизацию для TAniIndikator
//        Подскажите.
}

  • 0
  • Модераторы
Опубликовано (изменено)
void __fastcall domThread::UpdateAnimation()
{
frm->aIndic->Visible  = false;
frm->aIndic->Enabled  = false;
}

незнаю как на си будет, но примерно так

void __fastcall domThread::Execute()
{
Synchronize( UpdateAnimation );
Terminate();
} 
Изменено пользователем ZuBy
  • 0
  • Модераторы
Опубликовано
3 часа назад, walexw сказал:

void __fastcall domThread::UpdateAnimation()
{
//        Действительно мой код без синхронизации.
//        Я просто не знаю какую команду надо ставить в синхронизацию для TAniIndikator
//        Подскажите.
}

Вот посмотрите справку System.Classes.TThread.Synchronize

Примеры на С++: ThreadSynchronize (C++) и TThreadYield (C++)

  • 0
Опубликовано
В ‎29‎.‎09‎.‎2016 в 13:29, ZuBy сказал:

void __fastcall domThread::UpdateAnimation()
{
frm->aIndic->Visible  = false;
frm->aIndic->Enabled  = false;
}

незнаю как на си будет, но примерно так


void __fastcall domThread::Execute()
{
Synchronize( UpdateAnimation );
Terminate();
} 

ZuBy, спасибо, все так и сделал, получилось то что надо!

  • 0
Опубликовано (изменено)
В 30.09.2016 в 19:50, walexw сказал:

Terminate();

это как гомеопатия

хуже не будет, но и смысла нет )

и в результате получили что весь код потока исполняется в главном потоке
т.е. и организация потока бессмысленна

Изменено пользователем krapotkin

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...