Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.01.09;
Скачать: [xml.tar.bz2];

Вниз

Выполнение по шагам   Найти похожие ветки 

 
hellmachine   (2003-12-23 00:58) [0]

Добрый вечер, мастера!
У меня есть задача представить выполнение некоторых вычислений по шагам, на подобие отладки, где вычисления выполняются в цикле до опр. момента, затем останавливаются, пользователь смотрит результат, нажимает "след. шаг" и вычисления продолжаюстся. Я попытаюсь привести здесь свое решение, а к вам просьба оценить его на на безопасность или элегантность :)
Заранее хочу оговориться, что опыта у меня в написании многопоточных приложений - ноль и возможно мой вариант, мягко говоря, не самый удачный или безопасный.
Такую задачу можно было бы решить и реализовав что-то наподобие стандартного мастера windows, но разбивать вычисления и помещать их в несколько обработчиков нажатся на кнопку "далее" мне показалось нездорово и я решил связаться с потоками.
Вот общая схема:
* вычисления выполняются в методе Execute потока
* в потоке объявляются события (TNotifyEvent) и при выполнении опр. условия они вызываюстя след. образом прямо из тела TMyThread.Execute без Synchronize (вроде как событие не метод):

if @FMyEvent <> nil then
begin
FMyEvemt(Self);
Suspend();
end;

* в обработчике этого события выводим данные на экран
* по нажатии на кнопку "след. шаг" - MyThread.Resume();

вроде все работает, но я меня терзают смутные сомнения - нельзя ли сделать проще/надежней


 
Юрий Зотов   (2003-12-23 02:13) [1]

> hellmachine (23.12.03 00:58)
> вроде как событие не метод

А обработчик события? Разве это не метод? Вот этот код: FMyEvent(Self) - разве это не есть вызов метода?

Он самый и есть. Да еще связанный с обновлением каких-то визуальных контролов - значит, этот метод как раз потоконебезопасный и его надо вызывать через Synchronize.

IMHO, здесь вполне уместно использовать примерно такую схему:

procedure TMyThread.CallMyEvent;
begin
// FMyEventAssigned - это булевское поле в классе потока
FMyEventAssigned := Assigned(FMyEvent);
if FMyEventAssigned then FMyEvent(Self)
end;

procedure TMyThread.Execute;
var
i: integer;
begin
i := 0;
// Проверка Terminated позволяет легко ввести кнопку "Стоп"
while not Terminated and (i <= Последний_шаг) do
begin
case i of:
0: ... // первая порция вычислений
1: ... // вторая порция вычислений
...
Последний_шаг: // последняя порция вычислений
end;
Synchronize(CallMyEvent); // Безопасное обновление экрана.
if FMyEventAssigned then Suspend;
Inc(i);
end
end;

А в обработчике кнопки "Следующий шаг" просто вызываем Resume.


 
hellmachine   (2003-12-24 15:15) [2]

спасибо - написал, работает;


 
hellmachine   (2003-12-24 23:17) [3]

при тестировании выяснилась одна интересная вешь: вычисления в самодельном потоке выполняются значительно медленее, чем в основном - даже при условии, что основной поток простаивает; причем установка приоритета потока слабо влияет на результат. как это побороть?

также была замечена очень интересная особенность: значительного ускорения выполнения можно достичь, тыкая мышкой на элементы управления (например, выделяя item"ы в TListView) - прирост производительности до 100%!!! как это понимать?!!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.01.09;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.45 MB
Время: 0.014 c
4-25671
Dido
2003-11-06 22:32
2004.01.09
Как создать обработчик события OnMouseClick у компонента Animate?


3-25240
GameBoy
2003-12-10 22:49
2004.01.09
Эксклюзивный режим


1-25417
MadAngel
2003-12-23 20:45
2004.01.09
Несколько вопросов по RichEdit


3-25209
www
2003-12-11 14:50
2004.01.09
Date и int


1-25305
CraKer
2003-12-23 01:31
2004.01.09
Открытие док файла..





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский