Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.08.2012, 18:48   #1
bakanaev
Форумчанин
 
Регистрация: 27.03.2012
Сообщений: 438
По умолчанию Потоки, правильно реализовал или нет?

Вроде сделал все правильно, но при нажатии кнопки (запуске программы) вылетает ошибка Access violation at address.
Программа проходит по списку ссылок содержащихся в ListBox, потом выполнят над ними действия и выводит результат в мемо. Работает в 3 потока.

Прошу объяснить почему вылетает эта ошибка?
Переменная вроде объявлена, память должна же под нее выделиться.
И вообще правильно ли сделал программу? Может есть способы проще и понятнее ?
Логика программы такова,
Нажимаем баттон. Запускаем функцию NextThread

Код:
procedure TMyThread.NextThread;
begin

if   I < Form2.ListBox1.Items.Count    then
   begin

  if first = true then // Проверяем происходит ли запуск функции в первый раз или нет, если да то создаем первые 3 потока иначе проверяем количество поток, если оно меньше 3 то создаем еще один, если потоков в данный момент и так 3 то вызываем таймер (переходим в режим ожидания)
  begin
     while I < 3 do
     begin
       with TMyThread.Create(True) do
          begin
                URL := Form2.ListBox1.Items[i];
                FreeOnTerminate := True;
                Priority := TPNormal;
                Resume;
              end;
             inc(i);
              Synchronize(J_Inc);// переменная J это счетчик потоков, вот тут то и вылетает ошибка Access violation at address.
           end;
           first := false;
     end
  else
    begin
      if J < 3 then
          begin
             with TMyThread.Create(True) do
              begin
                URL := Form2.ListBox1.Items[i];
                FreeOnTerminate := True;
                Priority := TPNormal;
                Resume;
              end;
             inc(i);
           Synchronize(J_Inc);
          end
      else
          begin
           Form2.Timer1.Enabled:=true;
          end;
    end;



   end;

end;

Код таймера

Код:
procedure TForm2.Timer1Timer(Sender: TObject);
begin
if J < 3  then 
  begin
   MyThread.NextThread();
   Timer1.Enabled:=False;
  end;

end;
bakanaev вне форума Ответить с цитированием
Старый 16.08.2012, 18:49   #2
bakanaev
Форумчанин
 
Регистрация: 27.03.2012
Сообщений: 438
По умолчанию

Код всей программы
Код:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdCookieManager,
  Vcl.ExtCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    ListBox1: TListBox;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  type
      TMyThread = class(TThread)

      private
       FResultString: TStringList;

        { Private declarations }
      protected
        procedure Execute; override;
        procedure Update;
        procedure NextThread;
        procedure  J_Inc ;
        procedure J_Dec ;

      public
      { Public declarations }
       URL : string;
      end;


var
  Form2: TForm2;
  MyThread: TMyThread;
  I:Integer = 0;
  J:Integer = 0;
  First:Boolean = true;



implementation

{$R *.dfm}
     ....


procedure  TMyThread.Update ;
begin
 Form2.Memo1.Lines.AddStrings(FResultString);
end;

//....................................................
 procedure  TMyThread.J_Inc ;
 begin
  Inc(J);
 end;

 //....................................................
procedure  TMyThread.J_Dec ;
 begin
  Dec (J);

 end;

//....................................................
procedure TMyThread.Execute;
var IdHttp1: TIdHTTP;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    CookieManager1: TIDCookieManager;
    j:integer;
    s:string;
begin

 IdSSLIOHandlerSocketOpenSSL1:=TIdSSLIOHandlerSocketOpenSSL.Create;
 CookieManager1:=TIDCookieManager.Create;
 IdHttp1:=TIdHTTP.Create;
 IdHttp1.IOHandler:=IdSSLIOHandlerSocketOpenSSL1;
 IdHttp1.CookieManager:=CookieManager1;
 IdHttp1.HandleRedirects:=true;
 S:= IdHttp1.Get(URL);
 FResultString:=TStringList.Create;
 IsolateText(s,'<a class="b-serp-item__title-link" href="','" onmousedown="rc',FResultString);
 Synchronize(Update);
 Synchronize(J_Dec);
 IdHttp1.Free;
 CookieManager1.Free;
end;
//....................................................
procedure TMyThread.NextThread;
begin

if   I < Form2.ListBox1.Items.Count    then
   begin

  if first = true then
  begin
     while I < 3 do
     begin
       with TMyThread.Create(True) do
          begin
                URL := Form2.ListBox1.Items[i];
                FreeOnTerminate := True;
                Priority := TPNormal;
                Resume;
              end;
             inc(i);
              Synchronize(J_Inc);
           end;
           first := false;
     end
  else
    begin
      if J < 3 then
          begin
             with TMyThread.Create(True) do
              begin
                URL := Form2.ListBox1.Items[i];
                FreeOnTerminate := True;
                Priority := TPNormal;
                Resume;
              end;
             inc(i);
           Synchronize(J_Inc);
          end
      else
          begin
           Form2.Timer1.Enabled:=true;
          end;
    end;



   end;

end;

//......................................................
procedure TForm2.Button1Click(Sender: TObject);
begin
 MyThread.NextThread();

end;
//...............................................................


                         ....

procedure TForm2.Timer1Timer(Sender: TObject);
begin
if J < 3  then
  begin
   MyThread.NextThread();
   Timer1.Enabled:=False;
  end;

end;

end.
bakanaev вне форума Ответить с цитированием
Старый 16.08.2012, 19:14   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Вроде сделал все правильно
??? Без обид, но это выкинуть и закопать.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 16.08.2012, 19:54   #4
Kix.IV
Участник клуба
 
Регистрация: 11.08.2012
Сообщений: 1,226
По умолчанию

Ужас какой. Поддерживаю GunSmoker'a.
Kix.IV вне форума Ответить с цитированием
Старый 16.08.2012, 19:58   #5
bakanaev
Форумчанин
 
Регистрация: 27.03.2012
Сообщений: 438
По умолчанию

Не обижаюсь)) Подскажите лучше как мне реализовать то? С потоками до этого не работал
bakanaev вне форума Ответить с цитированием
Старый 16.08.2012, 19:59   #6
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Так ты ж не сказал, что хочешь реализовать.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 16.08.2012, 20:04   #7
bakanaev
Форумчанин
 
Регистрация: 27.03.2012
Сообщений: 438
По умолчанию

Программа проходит по списку ссылок содержащихся в ListBox ( в несколько потоков) , выполняет действия над исходным кодом и выводит результат в мемо.
Ссылок ~25к
bakanaev вне форума Ответить с цитированием
Старый 16.08.2012, 20:06   #8
bakanaev
Форумчанин
 
Регистрация: 27.03.2012
Сообщений: 438
По умолчанию

Реализовать не могу именно потоки, то есть как сделать так что бы скажем запускаем первые 3 потока, как один поток удалился на его место вызывается другой, и так далее пока не пройдемся по всему списку урлов
bakanaev вне форума Ответить с цитированием
Старый 16.08.2012, 20:14   #9
Kix.IV
Участник клуба
 
Регистрация: 11.08.2012
Сообщений: 1,226
По умолчанию

Ну например: в конце кода потока вызывать процедуру, которая будет создавать новый поток.
Или лучше в коде потока сделать цикл, который будет сам брать подходящую ссылку и исключать её, дабы другой поток её не обработал.
Kix.IV вне форума Ответить с цитированием
Старый 16.08.2012, 20:18   #10
bakanaev
Форумчанин
 
Регистрация: 27.03.2012
Сообщений: 438
По умолчанию

Цитата:
Сообщение от Kix.IV Посмотреть сообщение
Ну например: в конце кода потока вызывать процедуру, которая будет создавать новый поток.
Пробовал реализовать, но что то не срослось, а чем именно мой код плох? какие моменты?
bakanaev вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Правильно или нет вот в чём вопрос но ошибок нет... Alexcool Помощь студентам 2 10.01.2010 13:55
правильно решена или нет?? durachok) Помощь студентам 1 27.12.2008 08:23
правильно или нет FreeZZZ Паскаль, Turbo Pascal, PascalABC.NET 9 26.12.2008 09:39
решена правильно или нет??? durachok) Паскаль, Turbo Pascal, PascalABC.NET 3 25.12.2008 15:24
Посоветуйте ,правильно или нет Михаил Юрьевич Общие вопросы Delphi 2 14.06.2008 22:02