Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Остановка/продолжение программы пользователем Добавлено: 14.08.12 21:03  

Автор вопроса:  merr
Добрых суток времени всем :)
Народ, кто-нибудь знает можно ли сделать так, чтоб юзер мог легким нажатием кнопки остановить выполнение процедуры, но без выхода из нее, а также нажатием (другой) кнопки продолжить выполнение именно с этого же места. Процедура представляет собой цикл с задержкой - чтоб юзер успел увидеть изменение параметров на экране.
Может есть функции такие специальные?

Ответить

  Ответы Всего ответов: 13  

Номер ответа: 1
Автор ответа:
 Millenium



ICQ: 629966 

Вопросов: 118
Ответов: 903
 Web-сайт: www.aliyev.us
 Профиль | | #1
Добавлено: 14.08.12 21:28
может.
Создай переменную
  1. Dim IsPaused As Boolean


а после перехватывай нажатие совей кнопки А для "паузы" и Б для "возобновления".

и при нажатии кнопки А İsPaused = True и обратно - Б İsPaused = False.

и в модуле проверяй,
if IsPaused = True Then

Ответить

Номер ответа: 2
Автор ответа:
 Avvelana



Вопросов: 2
Ответов: 18
 Профиль | | #2 Добавлено: 14.08.12 21:29
Хм. Функции есть, но боюсь их реализация не стоит полученного результата. Вообще нужно использовать функции отладки. Думаю как-то так: Cоздаём новый поток, отправляем обработку текущей функции туда (SetThreadContext или что-то подобное). При этом предусматриваем механизм, чтобы функция продолжала работать в новом потоке. Далее делаем DebugBreak() или Sleep() на поток. Отрабатываем в новом потоке то, что нужно, далее передаём управление первому потоку, убиваем второй (что довольно сложно сделать правильно, очистка памяти и тд.) и продолжаем первый (ContinueDebugEvent или что-то подобное). В общем это будет кошмар, я бы не связывался с такими штуками. Возможно есть другие методы, но мне на ум ничего больше не приходит.

Ответить

Номер ответа: 3
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #3 Добавлено: 14.08.12 22:12
К сожалению автор не указал язык реализации, но если речь идет о .НЕТ, то там для этих целей есть куча возможностей. Это,собственно, все наследники WaitHandle (к примеру ManualResetEvent).Кроме того есть еще всякие Mutex, Semaphore и прочие прибамбасы которые тоже вполне подойдут для этих целей.. Да даже обычную критическую секцию в виде Monitor.Enter/Lock можно приспособить чтоб заморозить тред

Ответить

Номер ответа: 4
Автор ответа:
 merr



Вопросов: 11
Ответов: 31
 Профиль | | #4 Добавлено: 14.08.12 22:54
Да, извините что не указал - на VB6 все это безобразие нужно проделать...

Ответить

Номер ответа: 5
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #5 Добавлено: 15.08.12 00:34
Millenium пишет:
и в модуле проверяй,
if IsPaused = True Then

Наоборот, невозможно разложить куб на два куба, биквадрат на два биквадрата и вообще никакую степень, большую квадрата, на две степени с тем же показателем. Я нашел этому поистине чудесное доказательство, но поля книги слишком узки для него.


"Приостановка процедуры" фактически означает приостановку потока, выполняющего эту процедуру. Windows поддерживает возможность остановки потока. Если не ошибаюсь, это делается фукнцией SuspendThread. После этого поток переходит в спящее состоянии до того момента как его не "разбудят". По понятным (надеюсь) причинам разбудить поток можно только из другого потока, который еще выполняется.

Это в теории.

На практике - есть ряд особенностей.

Например, в VB6 вся программа выполняется в единственном потоке, который выполняет цикл обработки сообщений Windows. Приостановка этого потока будет означать полное зависание программы (перестанет отрисовываться UI и отвечать на действия пользователя), и возобновить выполнение программы уже будет невозможно.
В твоем случае запускать выполнение нужно в другом потоке (не UI потоке) и его же останавливать из UI потока.

Кроме того, асинхронная остановка потока (когда поток останавливается по команде извне, а не по собственной инициативе) - очень опасная практика которую нужно использовать с осторожностью (вернее вообще не использовать). Восновном проблемы связаны с тем, что не известно, что именно будет выполнять поток в момент своей остановки. А он может заниматься выделением памяти, созданием объектов ядра, выполнением транзакции и т.п. За подробностями гуглите "Why you should not suspend thread"

Если требуется возможность приостанавливать выполнение процедуры, такая возможность должна быть предусмотрена в самой процедуре. Например, в цикле периодически проверяется какой-то флаг, и если он установлен (а это может быть сделано из другого потока), то поток самостоятельно переводит себя в спящее состояние (способов хватает, обычно это делают объектами синхронизации режима ядра).

Это в теоритической практике.

А в практической практике на VB6 об этом фактически можно забыть. Запуск нового потока в VB6 займет примерно столько же времени сколько изучения C# на уровне, достаточном для того чтоб писать программы, котоыре ты пишешь сейчас.

Так вот, дорогой анон, если тебе удалось запустить поток (что делается несколько сложнее чем в самом С++), и ничего не упало, это не значит что твои приключения закончились. Поскольку после запуска потоков тебе потребуется делать синхроинзацию (что сравнимо по сложности с тем как это делается в С++), а также делать отладку программы (что уже практически невозможно). В любом случае про отшумевший Rapid Application Development и программирование мышкой можно будет забыть, для любого чиха нужно будет юзать голые функции Win32API (если, конечно, кто-то уже не умудрился запилить библиотеку классов для многопоточности под VB6, вот только кто, как и на***?)

=============================================

ну а вообще возникюет вопрос
Например, как у тебя сейчас вообще во время выполнения длительной процедуры "нажимается" кнопка если весь UI должен по идее висеть.

=========================

Реализация того что ты хотел без многопоточности возможна. При этом нужно будет смириться с тем, что производительность просядет (не знаю насколько, возможно, даже в разы), несмотря на то что нагрузка на процессор останется без изменнеий
Для этого нужно:

1) В каждой итерации цикла вызывать Application.DoEvents()
2) Реализовать механизм, котоыре позволяет сохранить состояние, в котором находится процедура и прервать ее выполнение, чтоб при следующем вызове она могла продолжить выполнение точно на том месте, на котором остановилась.
3) Либо же во время "приостановки" просто заходить в пустой цикл с одним лишь Application.DoEvents(), но будь готов к полной загрузке процессора (впрочем, владельцы 8-ядерных Core i7 вряд ли заметят подставу).

Вобщем найти хоть какое-нибудь разумное обоснование заниматься этой ***й (вместо того чтоб взять наконец и выучить С++, C# или Java) я лично не могу.

Ответить

Номер ответа: 6
Автор ответа:
 merr



Вопросов: 11
Ответов: 31
 Профиль | | #6 Добавлено: 15.08.12 01:35
Artyom, спасибо столь подробный ответ!
Запуск нового потока в VB6 займет примерно столько же времени сколько изучения C# на уровне, достаточном для того чтоб писать программы, котоыре ты пишешь сейчас.
Все сказано :)
У меня далеко не i7, с DoEvents в цикле приложение мертво висит.
Абсолютно согласен, нужно переходить на C#... После полугода VB6 это много легче, чем с нуля

Ответить

Номер ответа: 7
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #7 Добавлено: 15.08.12 10:17
Вопрос не языка а реализации. Юзать SuspendThread - дурное правило. Процедура должна сама предусматривать возможные точки останова. Как ты их реализуешь - через евенты, таймеры или как то еще - дело хозяйское.
А использовать DoEvent в каждой минимальной итерации - не просто изврат. Это Ахтунг!

Ответить

Номер ответа: 8
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #8 Добавлено: 15.08.12 11:07
LamerOnLine пишет:
Юзать SuspendThread - дурное правило

Так никто и не говорил про Suspend. Более того в НЕТ он является depricated. А предложенный мною WaitHandle являются стандартным механизмом синхронизации и проверен уже не одну сотню раз.
LamerOnLine пишет:
Процедура должна сама предусматривать возможные точки останова.

Именно это и предусматривает использование WaitHandle

Ответить

Номер ответа: 9
Автор ответа:
 LamerOnLine



ICQ: 334781088 

Вопросов: 108
Ответов: 2822
 Профиль | | #9 Добавлено: 16.08.12 14:13
Про SuspendThread упомянул Artyom. Что в этом такого если у человека такой стиль программирования - использовать в основном deprecated функции и помечать результирующий код как deprecated. Такой вот своеобразый стайл :)

Ответить

Номер ответа: 10
Автор ответа:
 Nash Bridges



Вопросов: 5
Ответов: 139
 Профиль | | #10 Добавлено: 18.08.12 04:57
Ему в первом посте сказали как делать.
Умничать не надо, а то горе от ума будет.

Ответить

Номер ответа: 11
Автор ответа:
 Nash Bridges



Вопросов: 5
Ответов: 139
 Профиль | | #11 Добавлено: 18.08.12 04:57
Ему в первом посте сказали как делать.
Умничать не надо, а то горе от ума будет.

Ответить

Номер ответа: 12
Автор ответа:
 BG(Алексей)



Вопросов: 26
Ответов: 295
 Профиль | | #12 Добавлено: 23.08.12 06:03
Artyom пишет:
1) В каждой итерации цикла вызывать Application.DoEvents()
Это просто жопа. Лучших тормозов придумат просто не возможно.

Ответить

Номер ответа: 13
Автор ответа:
 BG(Алексей)



Вопросов: 26
Ответов: 295
 Профиль | | #13 Добавлено: 23.08.12 06:07
Нужно, всего лишь, забыть про усопший VB6 и загрузить VB.Net

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам