Малко помощ?

6 отговора 0 прегледа
#1

Малко помощ?

Малко ми е трудно да обесня какво точно правя и какво точно не се получава, но ще се опитам.

Имам процедура която в един вътрешен за нея цикъл създава N на брой TThread-а - да кажем някъде към 5000 като се изчаква ако активните, създадени, TThread-ове са повече от 8 (вътрешно ограничение). Нещо от типа на:
 


var
FInThreads:Boolean; // Глобална променлива
FAskStop:Boolean; // Глобална променлива
FStartEnum:Boolean; // Глобална променлива
FRunningThreads:Integer = 0; // Глобална променлива

procedure StartThreads;
var
iCount:integer;
begin
FAskStop:=False;

try
try
For iCount:=0 to 4999 do
begin
FStartEnum:=True;
FCounterGuard.Enter; // FCounterGuard е TCriticalSection
try
Application.ProcessMessages;

if FAskStop then
begin
Exit;
end;

with TMyThread.Create(blah-blah) do
OnTerminate:=ThreadDone;

Inc(FRunningThreads);

finally
FCounterGuard.Leave;
end;

while FRunningThreads=MAX_ALLOWED_THREEADS do // 8 Threads
begin
Application.ProcessMessages;
Sleep(100);
end;
end;

except
// nothing
end;
finally
FStartEnum:=False;
end;

end;

procedure ThreadDone(Sender: TObject);
begin
FCounterGuard.Enter;
try
Dec(FRuningThreads);

//
// Blah-Blah-Blah
//

FInThreads:=(FRunningThreads>0) or FStartEnum;

finally
FCounterGuard.Leave;
end;

end;



От друга процедура, при "click" на бутон, някъде по средата на цикъла, присвоявам на
 FAskStop:=TRUE 
Според документацията, Exit би трябвало да предизвика спиране на for.. do и излизане от процедурата, без да нарушава try.. finally . Но при мен, Delphi 2010, това не се получава:


finally
FStartEnum:=False;
end;

никога не се извиква, при принудителен Exit
Някаква идея как да разреша този проблема?

Отговор
в отговор на ИвKo #2

Re: Малко помощ?

За излизане от for...to...do използвай "Break" и след това Exit, защото "Exit" ще те "изпрати" след "finally", ако се извиква в тялото на try...finally :), въпреки че не го пише в документацията (така е и в Delphi 5) :)

Редактирано от SAGE_BS на

Отговор
в отговор на SAGE_BS #3

Re: Малко помощ?

Открих си грешката, не е в конструкцията на процедурата.
Exit не ме изпраща след finally, а отива точно в тялото на finally... end; Break не разрешава проблема, той само ще ме "изкара" извън for, while, и т.н., но няма да ме прати директно в finally... end
Както и да е, проблема бе другаде... Благодаря все пак.

Отговор
в отговор на ИвKo #4

Но е много странно

Но е много странно (меко казано) в процедура, създаваща нишки, да ползваш ProcessMessages.
След като сме пичове и ползваме нишки, какво пречи нишките да си ги създаваме в отделна нишка, щом искаме главната нишка да си работи независимо?

Отговор
в отговор на NikB #5

Re: Но е много странно

Много ли се изложих?

Май ще трябва да си променя логиката... Най-малкото - това...

Какво се опитвам да направя:
- При някакъв Action, се стартират N на брой нишки, като работещите такива не могат да бъдат повече от X броя едновременно.
- Потребителя не може да предприеме никакви други действия, освен да спре създаването на нови нишки и "терминирането" на работещите такива, чрез някакъв Action. Макар да няма никакво значение, броя на нишките в масовия случай е към 8000 - 10 000.
- Докато има активен поне една нишка, приложението не може да се затваря.
- Докато има активни нишки, приложението трябва да може да се мести по екрана, да се минимизира и т.н...

Сигурно малко ми е акъла, но по време на "писането на кода", това ми "текна"..

Отговор
в отговор на ИвKo #6

Не, не си се изложил :)

Не, не си се изложил, бъди с самочувствие, всичко е по силите ти.
Просто трябва да имаш глобални променливи, които да се увеличават при създава/стартиране на нишките и да се намаляват при приключване и унищожаване.
Добре е да има и списък с нишките, чакащи стартиране (впрочем, има алтернатива - да ги създаваш в момента на необходимост/възможност от стариране).
Така ще имаш критери и за разрешаване на завършването на програмата.

Отговор
в отговор на NikB #7

Re: Не, не си се изложил :)

Благодаря.
Ще се постарая да си "ревизирам" кода

Отговор