Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
SpDS
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 34
1

Программа не отвечает при большом количестве введенных данных

13.08.2018, 01:43. Просмотров 735. Ответов 14
Метки нет (Все метки)

Привет всем. В общем проблема такая, есть программа, в которую загружается текстовый документ, необходимо вывести тест из него в memo построчно(выполнено), подсчитать количество строк и количество дублирующихся строк. Все работает, но если вводится например 4000 строк программа зависает и перестает отвечать. Помогите решить проблему.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
procedure TForm1.sButton1Click(Sender: TObject);
var
  i,j: integer;
  count : integer;
begin
count:=0;
if sOpenDialog1.Execute then
  begin
      sMemo1.Lines.LoadFromFile(sopendialog1.FileName);
      Caption := '' + ExtractFilename(sopendialog1.FileName);
//      Caption:=OpenDialog1.FileName;
  sLabel1.Caption := sLabel1.Caption+' '+IntToStr(sMemo1.Lines.Count);
end;
begin
for i:=0 to smemo1.Lines.Count-1 do
for j:=i+1 to smemo1.Lines.Count-1 do
begin
if smemo1.Lines[j]=smemo1.Lines[i] then
count:=count+1;
end;
end;
sLabel2.Caption := sLabel2.Caption+' '+IntToStr(count);
end;
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.08.2018, 01:43
Ответы с готовыми решениями:

Как освобождать память при большом количестве записей в TQuery?
Доброе время суток, Вопрос такой, как освобождать память при большом ...

Поиск в большом количестве документов word
Доброго времени суток, уважаемые форумчане! Столкнулся с необходимостью поиска...

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

Вывести сообщение о количестве строк, введенных в написанный мной редактор
Здравствуйте! В Delphi сделал Notepad. Сначала нужно ввести любые строчки в...

При потере фокуса текстовым полем txtTest определить тип введенных в текстовое поле данных
Написать языком ООП (Delphi или Visual Basic) процедуру обработки события для...

14
GoodWeather
142 / 141 / 59
Регистрация: 28.02.2017
Сообщений: 858
13.08.2018, 02:23 2
"Перестаёт отвечать" это не обязательно ошибка, просто она долго над чем-то думает.
Так-то следует вынести обработку в отдельный поток.
Или просто подождать ещё минут 15. С:
1
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,749
13.08.2018, 02:37 3
Цитата Сообщение от GoodWeather Посмотреть сообщение
Так-то следует вынести обработку в отдельный поток.
Нафига? Достаточно заменить TMemo на невизуальный TStringLiist.

Добавлено через 1 минуту
Есть ещё одно решение, но оно из разряда "вредных советов" в данном случае.
0
SpDS
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 34
13.08.2018, 02:39  [ТС] 4
GoodWeather, я уже думал над потоками. Но еще не работал с ними ни разу
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,749
13.08.2018, 02:41 5
SpDS, в данной задаче вам потоки не нужны от слова совсем.
0
GoodWeather
142 / 141 / 59
Регистрация: 28.02.2017
Сообщений: 858
13.08.2018, 02:48 6
Не-а. Он ж не меняет строки, а только читает. Будет почти без разницы. Разве что избавимся от перерисовки после LoadFromFile(), но это семечки.

Там есть нюансы всякие, но при такой простой тестовой задаче будет не сложно.
0
northener
пофигист широкого профиля
3423 / 2323 / 630
Регистрация: 15.07.2013
Сообщений: 13,749
13.08.2018, 02:52 7
GoodWeather, ну и зачем тут доппотоки?
0
SpDS
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 34
13.08.2018, 03:28  [ТС] 8
Решил все же сделать потоками, почитал теорию, получилось так:
Delphi
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
unit Unit1;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, sMemo, sLabel, sButton,
  sGroupBox, sDialogs, Vcl.ComCtrls, Unit2;
 
type
  TForm1 = class(TForm)
    sGroupBox1: TsGroupBox;
    sButton1: TsButton;
    sLabel1: TsLabel;
    sLabel2: TsLabel;
    sLabel3: TsLabel;
    sLabel4: TsLabel;
    sMemo1: TsMemo;
    sOpenDialog1: TsOpenDialog;
    procedure sButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.sButton1Click(Sender: TObject);
var
   Thread1: TThread1;
begin
   Thread1:=TThread1.Create(False);
end;
 
end.
Delphi
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
unit Unit2;
 
interface
 
uses
Classes;
 
type
TThread1 = class(TThread)
private
 
protected
procedure ShowResult;
procedure Execute; override;
end;
 
implementation
 
uses
SysUtils, Unit1;
//ПРоцедура для вывода инормации из потока
procedure TThread1.ShowResult;
begin
Form1.sLabel2.Caption := Form1.sLabel2.Caption+' '{+IntToStr(count)};
end;
//Длинная процедура
procedure TThread1.Execute;
var
  i,j: integer;
  count : integer;
begin
count:=0;
if Form1.sOpenDialog1.Execute then
  begin
      Form1.sMemo1.Lines.LoadFromFile(Form1.sOpendialog1.FileName);
      Form1.sLabel1.Caption := '' + ExtractFilename(Form1.sOpendialog1.FileName);
//      Caption:=OpenDialog1.FileName;
  Form1.sLabel1.Caption := Form1.sLabel1.Caption+' '+IntToStr(Form1.sMemo1.Lines.Count);
end;
begin
for i:=0 to Form1.sMemo1.Lines.Count-1 do
for j:=i+1 to Form1.sMemo1.Lines.Count-1 do
begin
if Form1.sMemo1.Lines[j]=Form1.sMemo1.Lines[i] then
count:=count+1;
end;
end;
Form1.sLabel2.Caption := Form1.sLabel2.Caption+' '+IntToStr(count)
end;
end.
Проблема в том, что при нажатии на кнопку не открывается диалог выбора файла. Специалисты по потокам, что скажете? Помогите найти и исправить ошибку)
0
GoodWeather
142 / 141 / 59
Регистрация: 28.02.2017
Сообщений: 858
13.08.2018, 03:40 9
northener, ТС писал код, имея тестовый файл в 10 строк. Всё было хорошо.
Потом он попробовал обработать файл в 4000 строк - и получил вроде как уже нехилый фриз. А если завтра понадобится обработать файл в 1600000 строк?
Что корректнее в такой ситуации делать? Зафигачить ProcessMessages? В редких случаях такое пройдёт безболезненно. Мож пусть уж сразу изучит все варианты?

SpDS, Блоги > krapotkin > Про потоки.
0
SpDS
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 34
13.08.2018, 03:47  [ТС] 10
GoodWeather, спасибо, я уже читал про потоки, и просил не этого.
0
GoodWeather
142 / 141 / 59
Регистрация: 28.02.2017
Сообщений: 858
13.08.2018, 04:50 11
Лучший ответ Сообщение было отмечено SpDS как решение

Решение

Цитата Сообщение от krapotkin
Сразу, в первой строке.
Потоки не должны ничего читать и писать в формах и компонентах!!!
А у вас что? С:
Первое же правило нарушено многократно)

На скорую руку и на коленке как-то примерно так:
Unit1
Delphi
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
Unit
      Unit1;
 
Interface
 
Uses
      Winapi.Windows,
      Winapi.Messages,
      System.SysUtils,
      System.Variants,
      System.Classes,
      Vcl.Graphics,
      Vcl.Controls,
      Vcl.Forms,
      Vcl.Dialogs,
      Vcl.StdCtrls;
 
Type
      TForm1=Class(TForm)
            Button1: TButton;
            Label1: TLabel;
            OpenDialog1: TOpenDialog;
            Procedure Button1Click(Sender: TObject);
      private
            Procedure WhenThreadDone(Sender: TObject);
      End;
 
Var
      Form1: TForm1;
 
Implementation
 
{$R *.dfm}
 
Uses
      Unit2;
 
Procedure TForm1.Button1Click(Sender: TObject);
Begin
      If OpenDialog1.Execute Then
            Begin
                  Button1.Enabled:=False;
                  TThread1.Create(OpenDialog1.FileName, WhenThreadDone).Start();
                  Label1.Caption:='Thread Working...';
            End;
End;
 
Procedure TForm1.WhenThreadDone(Sender: TObject);
Begin
      With TThread1(Sender) Do
            Begin
                  Label1.Caption:='"'+FileName+'" :: '+IntToStr(FLinesCount)+' :: '+IntToStr(FUnicCount);
            End;
      Button1.Enabled:=True;
End;
 
End.
Unit2
Delphi
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
Unit
      Unit2;
 
Interface
 
Uses
      System.Classes,
      System.SysUtils;
 
Type
      TThread1=Class(TThread)
      private
            FFileName: String;
            FStringList: TStringList;
      protected
            Procedure Execute(); override;
      public
            FLinesCount, FUnicCount: Integer;
            Constructor Create(AFileName: String; ATermProc: TNotifyEvent); overload;
            Destructor Destroy(); override;
      published
            Property FileName: String read FFileName;
      End;
 
Implementation
 
Constructor TThread1.Create(AFileName: String; ATermProc: TNotifyEvent);
Begin
      Inherited Create(True);
      FreeOnTerminate:=True;
      OnTerminate:=ATermProc;
      FStringList:=TStringList.Create();
      FFileName:=AFileName;
      FLinesCount:=0;
      FUnicCount:=0;
End;
 
Destructor TThread1.Destroy();
Begin
      FreeAndNil(FStringList);
      Inherited Destroy();
End;
 
Procedure TThread1.Execute();
Var
      i, j: Integer;
Begin
      If FileExists(FFileName) Then
            Begin
                  FStringList.LoadFromFile(FileName);
                  FFileName:=ExtractFileName(FFileName);
                  FLinesCount:=FStringList.Count;
                  //////////////////////////////////////////////////////////////
                  FUnicCount:=0;
                  For i:=0 To FStringList.Count-1 Do
                        For j:=i+1 To FStringList.Count-1 Do
                              If FStringList[j]=FStringList[i] Then
                                    Inc(FUnicCount);
                  //////////////////////////////////////////////////////////////
            End;
End;
 
End.
0
SpDS
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 34
13.08.2018, 09:12  [ТС] 12
GoodWeather, спасибо, разобрался в ситуации)
0
Waitman
0 / 0 / 0
Регистрация: 20.08.2018
Сообщений: 10
20.08.2018, 23:16 13
SpDS Вы смотрели есть ли разница при чтении фала с SSD и HDD, мне интересно где узкое горлышко, у меня похожая задача но только там далеко не 4000 строк, и такую кучу в оперу не загрузишь..
0
GoodWeather
142 / 141 / 59
Регистрация: 28.02.2017
Сообщений: 858
21.08.2018, 00:36 14
Читать файл блоками. Вроде был класс подходящий, что-то из этого: http://docwiki.embarcadero.com/RADSt...he_RTL_and_VCL
0
SpDS
0 / 0 / 0
Регистрация: 31.10.2016
Сообщений: 34
21.08.2018, 22:16  [ТС] 15
Waitman, решил проблему потоками.

Добавлено через 20 секунд
Waitman, разница не существенная
0
21.08.2018, 22:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.08.2018, 22:16

memo статус бар тормозит при большом объёме
Привет всем =) сталкнулся вот таким проблемой, статус бар тормозит при большом...

Вращение 3д графика при большом количестве выводимых данных
Здравствуйте. При работе в Wolfram Mathematica 9.0.1 меня посетила следующая...

Не ляжет ли БД при большом количестве запросов
Увидел такой коммент на одном из ресурсов Добрый день, Андрей. Я пытался...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru