Помогите с потоками С++

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by leva39, 14 Apr 2012.

  1. leva39

    leva39 New Member

    Joined:
    11 Apr 2012
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    В общем пишу парсер рамблера собирает почты с рамблер новостей а на другой странице программы собирает почты с сообществ рамблера.
    Как он работает:
    1. Заходим на рамблер новости и ищем там все комментарии http://news.rambler.ru/13511046/comments/
    Что то типо такой ссылки копируем её в программу теперь опускаемся в низ смотрим количество страниц с комментариями доходим до последней записываем ёё в программу.
    2.Нажимаем парсить.
    3. Ждём сохраняем, всё.

    Вот так должно быть сейчас в программе всё работает но при нажатии на парсить форма виснет и ни чего не сделать пока не закончит парсинг хоть он и происходит в отдельном потоке но форма висит.

    Вот код главного файла Unit1.h
    Code:
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include "Unit3.h"
    #include "Unit1.h"
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    Memo1->Clear();                                   //Кнопка отчистить 1
    Memo2->Clear();
    
    
    HMENU MenuHandle = GetSystemMenu(Handle, false);
    if(MenuHandle)                                                //Запрет максимизации формы
      DeleteMenu(MenuHandle, SC_MAXIMIZE, MF_BYCOMMAND);
    }
    
    
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
       Memo1->Clear();
       StaticText1->Caption=" ";
       StaticText4->Caption=" ";                                 //Отчистить
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    if(SaveTextFileDialog1->Execute()){
    	   Memo1->Lines->SaveToFile(SaveTextFileDialog1->FileName);   //Сохранение в файл 1
    }
    }
    //---------------------------------------------------------------------------
    
    
    void __fastcall TForm1::Button4Click(TObject *Sender)
    {
    TMyThread1 *Thread1= new TMyThread1(true);
    Thread1->FreeOnTerminate = true;                   ///Создания потока для парсинга С СООБЩЕСТВ !
    Thread1->Resume();
    
    }
    
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button7Click(TObject *Sender)
    {
     AnsiString o1=0;
     TIdHTTP *http1 = new TIdHTTP(0);
    o1 = http1->Get(Edit3->Text);
    int positionone;
    int positiontwo;                             //Получаем конечную страницу
    positionone=o1.Pos(("Последняя страница"))+20;        //>
    positiontwo=o1.Pos(("</a>&nbsp;&nbsp;<a title="));
    o1=o1.SubString(positionone,positiontwo-positionone);
    positionone=o1.Pos(("p="))+2;
    positiontwo=o1.Pos((">"))-1;
    o1=o1.SubString(positionone,positiontwo-positionone);
    Edit4->Text=o1;                                     //Вывод количества страниц (последней страницы)
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    TMyThread *Thread= new TMyThread(true);
    Thread->FreeOnTerminate = true;                   //Создания потока для парсинга новостей
    Thread->Resume();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button6Click(TObject *Sender)
    {
     Memo2->Clear();
     StaticText3->Caption=" ";                        //Кнопка отчистить 2
     StaticText2->Caption=" ";
    }
    //---------------------------------------------------------------------------
    
    
    
    void __fastcall TForm1::Button5Click(TObject *Sender)
    {
    if(SaveTextFileDialog1->Execute()){                                  //Сохранить 2
    	   Memo2->Lines->SaveToFile(SaveTextFileDialog1->FileName);
    }
    }
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    
    
    

    Код первого потока

    Code:
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    #include "Unit2.h"
    //#include "Unit1.cpp"
    #pragma package(smart_init)
     AnsiString cyb=0,p=0,o;
     TIdHTTP *http = new TIdHTTP(0);
    //---------------------------------------------------------------------------
    
    //   Important: Methods and properties of objects in VCL can only be
    //   used in a method called using Synchronize, for example:
    //
    //      Synchronize(&UpdateCaption);
    //
    //   where UpdateCaption could look like:
    //
    //      void __fastcall TMyThread::UpdateCaption()   Terminate()
    //      {
    //        Form1->Caption = "Updated in a thread";
    //      }
    //---------------------------------------------------------------------------
    
    __fastcall TMyThread::TMyThread(bool CreateSuspended)
    	: TThread(CreateSuspended)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TMyThread::Execute()
    {
    
    Synchronize(&Go);
    }
    
    
    
    
    void __fastcall TMyThread::Go()
    {
           o=(Form1->Edit2->Text);
    for(int o =1;o<=(Form1->Edit2->Text.ToInt());o++)
    {
    cyb = http->Get(Form1->Edit1->Text+(("?cpage=")+IntToStr( o )));   // Берём ссылку добавлеям кней количество введенных страниц.
    Form1->StaticText4->Caption=+o;        //текушяя страница
    for(int i = 0; i < 100; i++){
    int positionone;
    int positiontwo;
    positionone=cyb.Pos(("50x50"))+6;           //Парсинг почт
    positiontwo=cyb.Pos("/?default=boy");
    Form1->Memo1->Lines->Add(cyb.SubString(positionone,positiontwo-positionone));   //Вывод почт в мемо1
    Form1->Memo1->Lines->Text=Trim(Form1->Memo1->Lines->Text);    //удаление пустых строк
    Form1->StaticText1->Caption=Form1->Memo1->Lines->Count;     //Вывод количества собранных почт
    cyb.Delete(1,cyb.Pos(("50x50"))+6);
    cyb.Delete(1,cyb.Pos("/?default=boy"));      //Удаления позиций
    if(Form1->CheckBox1->State==cbChecked){
    Form1->Memo1->Lines->SaveToFile("mails.txt");        //Если да то автосохранение почт в mail2.txt
    }
    }
    }
       delete http;
    
    }
    
    
    
    
    
    
    
    
    
    
    
    
    //---------------------------------------------------------------------------
    3 поток аналогичны 2 только парсинг не с новостей а с сообществ рамблера.
    Кто может сказать как решить проблему с зависанием.
     
  2. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Нельзя такое говно делать из дополнительного потока:
    У тебя об этом даже в комментариях выше написано.
    Также ТС, пиши не отчистить, а очистить!
     
  3. leva39

    leva39 New Member

    Joined:
    11 Apr 2012
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Не понял тебя а как же делать тогда.?
    П.С все комменты мои
     
  4. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    К элементам формы из потока надо обращаться через Synchronize()\крит секции.

    Code:
    Form1->StaticText4->Caption=+o;        //текушяя страница
     
  5. leva39

    leva39 New Member

    Joined:
    11 Apr 2012
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    А я как кним обращаюсь? У меня вроде void __fastcall TMyThread::Execute()
    {

    Synchronize(&Go);
    }

    Я с потоками раньше не работал если можешь показать пример на моеё коде?
     
  6. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    Не увидел, сорри,
     
  7. Kaimi

    Kaimi Well-Known Member

    Joined:
    23 Aug 2007
    Messages:
    1,732
    Likes Received:
    811
    Reputations:
    231
    А вот если бы ты догадался не пихать весь код парсера в тело Go, то все могло бы быть иначе, но нет...
     
    _________________________
    1 person likes this.
  8. leva39

    leva39 New Member

    Joined:
    11 Apr 2012
    Messages:
    6
    Likes Received:
    0
    Reputations:
    0
    Я не знаю как разбить код он там цикл в цикле не могу я его разобрать вроде как.
     
  9. ree4

    ree4 New Member

    Joined:
    9 Mar 2011
    Messages:
    28
    Likes Received:
    2
    Reputations:
    0
    К компонентам из потока обращаться - идиотизм полный.
    Проще создай стринглисты и в них грузи.
    По хорошему создать класс, который будет виден форме и тредам. С потока передаёшь текст классу в стринглист, на форме просто получаешь текст этого листа