Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Dev express Grid и поток 
:(
    Опции темы
0x00
  Дата 27.7.2010, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 192
Регистрация: 3.4.2006

Репутация: нет
Всего: нет



Возникла проблема. 
На форме лежит cxGrid1, oraQuery1, oraDataSource.
Форма представляет из себя форму поиска.
Поиск сложный, по нескольким таблицам с от 100 до 20 000 000 записей в каждой.
Все работает медленно и пока выполняется запрос вся программа зависает.
Решил засунуть выполнение запроса в поток.

Код

DWORD WINAPI Searcher(LPVOID lpParam){
    search_form->Search_btn->Enabled = false;

    search_form->srez->Active = false;
    search_form->srez->SQL->Clear();
    search_form->srez->SQL->Add(SQL);
    search_form->srez->Active = true;

    TerminateThread(searchar_loader_h, 1);

    search_form->pbar->Position = 0;
    search_form->Search_btn->Enabled = true;
    try{
        search_result_form->cxButton2->Enabled = true;
    }catch(...){;}
}


поток создаю так:

Код

    DWORD searcher_th;
    searcher_h = CreateThread(NULL, 0, &Searcher, 0, 0, &searcher_th);


в потоке все отрабатывает прекрасно, но есть одно НО!
При прорисовке грида вылетает неуловимая ошибка Access violation (в конце концов грид прорисовывается, но справа нет скроллбара).
Методом тыков обнаружил что если перед выполнением потока сделать this->cxGrid1->Visible = false; и после его выполнения соответственно this->cxGrid1->Visible = true;, то все отрабатывает без Access violationОВ.

Ктонибудь сталкивался с подобной проблемой?
PM MAIL   Вверх
borisbn
Дата 27.7.2010, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 18
Всего: 135



Если ты из потока вызываешь VCL-компоненты, то понятно, что у тебя всё падает. Этого делать нельзя.
Чтобы из отдельного потока добираться к визуальным компонентам нужно
1. Наследоваться от TThread
2. Написать функцию Execute
3. Сделать в ней невизуальные действия
4. Вызвать Synchronize( drawOnGrid )
5. А уже в функции drawOnGrid дёргать VCL-компоненты

кури TThread и Synchronize


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
0x00
Дата 28.7.2010, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 192
Регистрация: 3.4.2006

Репутация: нет
Всего: нет



Цитата(borisbn @ 27.7.2010,  16:54)
Если ты из потока вызываешь VCL-компоненты, то понятно, что у тебя всё падает. Этого делать нельзя.
Чтобы из отдельного потока добираться к визуальным компонентам нужно
1. Наследоваться от TThread
2. Написать функцию Execute
3. Сделать в ней невизуальные действия
4. Вызвать Synchronize( drawOnGrid )
5. А уже в функции drawOnGrid дёргать VCL-компоненты

кури TThread и Synchronize

я конечноже пробывал и стандартный билдеровский tthread.
от Synchronize( drawOnGrid ) нету толка, он блокирует доступ к обьектам над которыми производятся операции и программа всеравно зависает при поиске
PM MAIL   Вверх
586
Дата 28.7.2010, 07:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Цитата(0x00 @  28.7.2010,  08:02 Найти цитируемый пост)
я конечноже пробывал и стандартный билдеровский tthread.
от Synchronize( drawOnGrid ) нету толка, он блокирует доступ к обьектам над которыми производятся операции и программа всеравно зависает при поиске 

Не допускай, чтобы синхронизация выполнялась долго, иначе прога будет зависать.
Если так напишешь:
Код
void __fastcall TMyThread::drawOnGrid()
{
    for(int i = 0; i < 10000; ++i)
    {
        //...
    }
}

void __fastcall TMyThread::Execute()
{
    Syncronize(onDrawGrid);
}

то действительно, программа зависнет.
А если напишешь так:
Код
void __fastcall TMyThread::drawOnGrid()
{
    //...
}

void __fastcall TMyThread::Execute()
{
    for(int i = 0; i < 10000; ++i)
    {
        Syncronize(onDrawGrid);
    }
}

Проблем быть не должно.

Это сообщение отредактировал(а) 586 - 28.7.2010, 07:24
PM   Вверх
0x00
  Дата 28.7.2010, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 192
Регистрация: 3.4.2006

Репутация: нет
Всего: нет



Ура! Нашел решение.

программа вываливается при прорисовке грида.
перед запуском потока 

Код

    this->cxGrid1->BeginUpdate();
    Search_thread *s_th = new Search_thread(true, searchar_loader_h, SQL);
    s_th->Resume();


и самое интересное в потоке sql запрос не в synchronize. в synchronize только прорисовка грида)

Код

//---------------------------------------------------------------------------

#include <vcl.h>
#include "mainsr.h"
#pragma hdrstop

#include "search_thread.h"
#include "srrez.h"
#pragma package(smart_init)

HANDLE loader_h = NULL;
String th_sql = "";

//---------------------------------------------------------------------------
__fastcall Search_thread::Search_thread(bool CreateSuspended, HANDLE loader_handle, String SQL):TThread(CreateSuspended)
{
    loader_h = loader_handle;
    th_sql = SQL;
}
//---------------------------------------------------------------------------
void __fastcall Search_thread::drawOnGrid(){
    search_result_form->cxGrid1->EndUpdate();
}
//---------------------------------------------------------------------------
void __fastcall Search_thread::Execute()
{
    search_form->Search_btn->Enabled = false;

    search_result_form->srez->Active = false;
    search_result_form->srez->SQL->Clear();
    search_result_form->srez->SQL->Add(th_sql);
    search_result_form->srez->Active = true;

    TerminateThread(loader_h, 1);

    search_form->pbar->Position = 0;
    search_form->Search_btn->Enabled = true;

    Synchronize( drawOnGrid );
}
//---------------------------------------------------------------------------


PM MAIL   Вверх
mrbrooks
Дата 28.7.2010, 07:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(0x00 @  28.7.2010,  08:30 Найти цитируемый пост)
и самое интересное в потоке sql запрос не в synchronize. в synchronize только прорисовка грида

что бы не делать таких открытий, рекомендую внимательней читать документацию или специализированную литературу. в ней все черным по белому написано зачем нужен Synchronize smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0484 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.