Program ma za zadanie wykonywanie operacji np na adresach www zawartych w TListViev aż do poprawnego sprawdzenia wszystkich adresów.
Operacje wykonywane są w watkach których naraz możne być np 5 operacja w wątku może się nie powieść należy ją powtarzać , aż wszystkie adresy zostaną poprawnie sprawdzone. Poprawność operacji true, false w tym testowym programie jest symulowana losowaniem.
Algorytm jaki wymyśliłem jest następujący. Do typu list STL ładuję nr z ListView i przekazuje do wątku wskaźnik do tej listy.
W zsynchronizowanej metodzie wątku PobierzStart(); usuwam dany element [liczbę] z listy tak by kolejny wątek nie wywołał tej samego adresu wywołuję operacje w Execute() i PobierzStop(); . W PobierzStop(); symuluje poprawność wykonania operacji jeśli jest poprawna nic nie robię z list jeśli nie wstawiam do niej z powrotem nr do ponownego sprawdzenia.
Cały kod główny formularza:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Timer1->Interval = 100;
Timer1->Enabled = false;
// Wypelniam testowo ListViev
for(int ii = 0; ii < 50; ii++)
{
TListItem * ElementListy = ListView1->Items->Add();
ElementListy->Caption = "Adres nr: "+(String) ii;;
ElementListy->SubItems->Add("---");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MyOnTerminate(TObject *Sender)
{
this->ileWatkow --;
StatusBar1->Panels->Items[1]->Text="Aktywnych wątków: "+IntToStr(this->ileWatkow);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
myList.clear();
for(int ii = 0; ii < 50; ii++)
{
myList.push_back(ii);
ListView1->Items->Item[ii]->SubItems->Strings[0] = "---";
}
// Uruchamiam timer ktory odpala watki
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if(this->ileWatkow < 5)
{
if(myList.size() == 0)
{
Timer1->Enabled = false ;
StatusBar1->Panels->Items[1]->Text="KONIEC";
StatusBar1->Panels->Items[0]->Text="Do sprawdzenia "+IntToStr(myList.size());
}
else
{
Watek = new MyWatek(true);
Watek->ListView1 = ListView1;
Watek->pointerList = &myList;
Watek->OnTerminate = MyOnTerminate;
Watek->Resume();
this->ileWatkow++;
StatusBar1->Panels->Items[0]->Text="Do sprawdzenia "+IntToStr(myList.size());
StatusBar1->Panels->Items[1]->Text="Aktywnych wątków: "+IntToStr(this->ileWatkow);
}
}
}
//---------------------------------------------------------------------------
Kod wątku:
#include <vcl.h>
#include <math.hpp>
#pragma hdrstop
#include "UnitMyWatek.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall MyWatek::MyWatek(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
this->tuNrNaList = 0;
}
void __fastcall MyWatek::PobierzStart()
{
// pobieram wartosc pierwszego elementu z listy i go usuwam
// po to by inny ruszajacy watek nie pobral tej samej wartosci
this->tuNrNaList = pointerList->front();
pointerList->remove(this->tuNrNaList);
ListView1->Items->Item[this->tuNrNaList]->SubItems->Strings[0] = "Start...";
}
//---------------------------------------------------------------------------
void __fastcall MyWatek::Execute()
{
Synchronize(&PobierzStart);
// Jakas czasowa operacja
Sleep(RandomRange(100, 2000));
Synchronize(&PobierzStop);
}
//---------------------------------------------------------------------------
void __fastcall MyWatek::PobierzStop()
{
// symuluje losowa poprawnosc operacji
randomize();
if(RandomRange(1, 10) >= 5)
{
ListView1->Items->Item[this->tuNrNaList]->SubItems->Strings[0] = "Wynik Dobry";
}
else
{
// operacja nie udana wiec trzeba ja powrorzyc w tym celu spowrotem
// dodaje wartosc do listy do ponownego wywolania w kolejnym przebiegu
pointerList->push_back(this->tuNrNaList);
ListView1->Items->Item[this->tuNrNaList]->SubItems->Strings[0] = "Wynik Zly";
}
}
Cały projekt w załączniku.
Problem jest taki, że bardzo często w TlstViev mam Wynik Zly, a z założenie operacja miała byc tak długo wykonywana, aż wszystkie wyniki będą poprawne "Wynik Dobry". Proszę o pomoc w poprawieniu - [wskazaniu błędu] tego kodu by działał zgodnie z oczekiwaniem.
--------





