Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
7 / 5 / 2
Регистрация: 25.05.2013
Сообщений: 112

Зависает форма при выполнении потока

14.09.2018, 23:25. Показов 2301. Ответов 0

Студворк — интернет-сервис помощи студентам
Всем привет!

Пишу на C++ Builder XE.

Пишу MDI-приложение.

1. Основной поток запускает главную форму.

2. Из главной формы можно открыть несколько экземпляров MDI-формы, которая запускает выполнение двух разных потоков, которые работают одновременно с двумя разными файлами по разным алгоритмам (Пусть первый поток будет ThrConversion, а второй ThrReadCatalog). Первый конвертирует бинарный файл, а второй - парсит текстовый файл.

То есть каждый экземпляр MDI-дочки запускает 2 потока, каждый из которых определяется в экземпляре MDI-дочки (то есть работает со своими адресами, как мне думается).

3. На MDI-дочках есть Label1 и Label2, которые выводят процент готовности выполнения потоков ThrConversion и ThrReadCatalog соответственно.

4. Есть запустить только 1 MDI- дочку, то все проходит хорошо, оба потока выполняются параллельно без ошибок, а на вызвавшей их MDI-дочке видно состояние работы.
Но если запустить вторую MDI-дочку, которая будет делать тоже самое, но с другими файлами, то все 4 потока выполняются и выполняются правильно, но визуальная часть приложения (формы основного потока) подвисают до тех пор, пока не завершатся все потоки, потом все работает нормально

Запуск потоков из MDI-дочки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Поток конвертера
    ThrConversion *ThrConverter=new ThrConversion(true);
    ThrConverter->FlightInformationFilePath=FlightInformationFilePath;
    ThrConverter->OutExt=OutExt;
    ThrConverter->WPS=WPS;
    ThrConverter->ConverterDllName=ConverterDllName;
    for(int i=0 ;i<4; i++)
    ThrConverter->Synx[i]=Synx[i];
    ThrConverter->HostClass=this;
    ThrConverter->FailureFrame=FailureFrame;
    ThrConverter->NullFrame=NullFrame;
    ThrConverter->lb=Label1;
    ThrConverter->Resume();
 
    //Поток чтения каталога
    ThrReadCatalog *ThrReadCat=new ThrReadCatalog(true);
    ThrReadCat->HostClass=this;
    ThrReadCat->AnPar=AnalogParameter;
    ThrReadCat->DisPar=DiscreteParameter;
    ThrReadCat->Resume();
Код потока Converter:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "UnitThrConversion.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
 
__fastcall ThrConversion::ThrConversion(bool CreateSuspended)
    : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall ThrConversion::ProcessState()
    {
        Progress=(Readed/(WPS*4)*100)/(InFileLength/(WPS*4));
        HostClass->Label1->Caption="Конвертирование: "+AnsiString(Progress)+"%";
    }
//---------------------------------------------------------------------------
void __fastcall ThrConversion::Execute()
    {
        FreeOnTerminate = true;
 
        Conversion = NULL;
        //Подключаем библиотеку
        DLLConverter = LoadLibraryA(ConverterDllName.c_str());
        if (!DLLConverter)
            {
                //ТУТ СООБЩЕНИЕ
                return;
            }
        Conversion = (DLLConverterFunc)GetProcAddress(DLLConverter, "_Conversion"); //Получаем указатель на функцию
        if (!Conversion)
            {
                //ТУТ СООБЩЕНИЕ
                return;
            }
        //Конвертируем
        Readed=0;
        InFileLength=0;
        Progress=0;
        Converted=false;
 
        Conversion( FlightInformationFilePath.c_str(),
                    AnsiString(ChangeFileExt(FlightInformationFilePath, OutExt)).c_str(),
                    WPS,
                    Synx,
                    &Readed,
                    &InFileLength,
                    FailureFrame,
                    NullFrame,
                    &Converted);
 
        while(!Terminated)
            {
                if(!Converted)
                    {
                        Synchronize(ProcessState);
                    }
                else
                    {
                       Synchronize(ProcessState); 
                        //Выгружаем библиотеку конвертера
                        FreeLibrary(DLLConverter); //Выгружаем библиотеку конвертера
                        Conversion = NULL;
                        Terminate();
                    }
            }
 
    }
//---------------------------------------------------------------------------
Код потока ThrReadCatalog:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <vector.h>
#include <StrUtils.hpp>
#pragma hdrstop
 
#include "UnitThrReadCatalog.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
 
__fastcall ThrReadCatalog::ThrReadCatalog(bool CreateSuspended)
    : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall ThrReadCatalog::ReadState()
    {
        Progress=(Readed*100)/CatalogLength;
        HostClass->Label2->Caption="Чтение каталога: "+AnsiString(Progress)+"%";
    }
//---------------------------------------------------------------------------
void __fastcall ThrReadCatalog::Execute()
{
    FreeOnTerminate = true;
 
    TStringList *Catalog = new TStringList;
    CatalogReadLog = new TStringList;
 
    Readed=0;
    CatalogLength=0;
    Progress=0;
 
    Catalog->LoadFromFile(HostClass->CatalogName);
    CatalogLength=Catalog->Count;
 
    for(int i=0; i<Catalog->Count; i++)
        {    
            //ТУТ что-то делаем
            Readed++;
            Synchronize(ReadState);
        }
    delete Catalog;
}
//---------------------------------------------------------------------------
Поток ThrConversion загружает и вызывает функцию из внешней DLL, там тоже реализованы потоки.

Методом научного тыка выяснилось, что проблема не в DLL. Я вообще убирал этот кусок с подключением библиотеки и использованием функции из нее. Проблема в строчке
C++
1
Synchronize(ProcessState);
в потоке ThrConversion.
Если ее убрать, то конвертирование происходит нормально, просто не отображается состояние на форме. Но даже если убрать из функции ProcessState() все содержимое (чтобы на форму ничего не выводилось), а Synchronize(ProcessState); оставить, то все равно подвисает.

При всем при этом если не запускать ThrConversion, а только ThrReadCatalog с выводом состояния на форму, то все работает без проблем с любым количеством экземпляров этого потока (Хотя там тоже есть Synchronize ). Виснет только ThrConversion.


Что тут может быть? В какую сторону гуглить ?

Спасибо!

Добавлено через 8 часов 21 минуту
Разобрался.
Нельзя так часто дергать Synchronize
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.09.2018, 23:25
Ответы с готовыми решениями:

Зависает форма при создании потока
Здравствуйте форумчане. Вчера тестировал работу 200 одновременных потоков на C++ Builder 6, все работало отлично. Сегодня форма...

При выполнении цикла форма подвисает
Доброе время суток форумчани, У меня возникла проблема. При выполнени цикла форма весит. Я этот цыкл вставил в событие обекта ТАЙМЕР1 и в...

Зависает форма при загрузке DLL
Я написал функцию и поместил ее в DLL.Если загружать эту DLL из программы которая открыта в билдере то функция работает,а если запустить...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.09.2018, 23:25
Помогаю со студенческими работами здесь

Зависает интерфейс при выполнении отдельного потока
Как сделать так чтобы при выполнении потока не зависалось GUI? Вот небольшой код: using System; using...

Зависает форма при выполнении цикла
Всем привет! Пытаюсь посредством цикла перемешать элементы массива, избегая повторов. Пользуюсь таким алгоритмом: randomize; i:=0;...

Зависает форма и RichTextBox при выполнении программы
Здравствуйте, форумчане! Возникла проблема с тем, что при выполнении кода зависает форма и отвисает только после завершения работы. ...

При выполнении кода форма зависает. Как вывести прогрессбар?
Пишу программу, которая должна с моего сайта скачать нудный файл, и старый заменить новым. Типа обновление программы. Проблема в том, что...

Зависает программа при выполнении цикла
Здравствуйте, на 3 кнопки написаны циклы, при их выполнении программа зависает, подскажите в чем проблема пожалуйста, за кривые коды не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru