Отмена длительного процесса в VB6.0 без DoEvents?

Можно ли отказаться от долгого процесса в VB6.0 без использования DoEvents?

Например:

for i = 1 to someVeryHighNumber ' Do some work here ' ... if cancel then exit for end if next Sub btnCancel_Click() cancel = true End Sub 

Я предполагаю, что мне нужно «DoEvents» до «if cancel then …», есть ли лучший способ? Прошло много времени…

Нет, вы поняли это правильно, вы определенно хотите DoEvents в своем цикле.

Если вы помещаете DoEvents в свой основной цикл и обнаруживаете, что слишком GetQueueStatus обрабатываете обработку, попробуйте вызвать функцию GetQueueStatus (которая намного быстрее, чем DoEvents) Windows API, чтобы быстро определить, нужно ли даже звонить в DoEvents. GetQueueStatus сообщает вам, есть ли какие-либо события для обработки.

 ' at the top: Declare Function GetQueueStatus Lib "user32" (ByVal qsFlags As Long) As Long ' then call this instead of DoEvents: Sub DoEventsIfNecessary() If GetQueueStatus(255) <> 0 Then DoEvents End Sub 

Нет, вы должны использовать DoEvents, иначе все события пользовательского интерфейса, клавиатуры и таймера будут оставаться в очереди.

Единственное, что вы можете сделать, это вызвать DoEvents один раз на каждые 1000 итераций или таких.

Является ли цикл «for» запущенным в streamе графического интерфейса? Если да, то вам понадобится DoEvents. Вы можете использовать отдельный stream, и в этом случае DoEvents не требуется. Вы можете сделать это в VB6 (не просто).

Вы можете запустить его на отдельном streamе, но в VB6 это королевская боль. DoEvents должны работать. Это взломать, но тогда и VB6 (10-летний ветеран VB говорит здесь, поэтому не меняйте меня).

Разделите задачу на длительную работу на кванты. Такие задачи часто управляются простым циклом, поэтому разрезайте его на 10, 100, 1000 и т. Д. Итераций. Используйте элемент управления таймером, и каждый раз, когда он срабатывает, выполняет часть задачи и сохраняет свое состояние во время движения. Для начала настройте начальное состояние и включите таймер. По завершении отключите таймер и обработайте результаты.

Вы можете «настроить» это, изменив количество работы на квант. В обработчике событий Timer вы можете проверить «отменить» и остановиться по мере необходимости. Вы можете сделать все это аккуратно, объединив рабочую нагрузку и таймер в UserControl с событием Completed.

Это хорошо работает для меня, когда мне это нужно. Он проверяет, нажал ли пользователь клавишу эвакуации, чтобы выйти из цикла.

Обратите внимание, что у него действительно большой недостаток: он обнаружит, что пользователь ударил ключ escape в ЛЮБОЙ программе – а не только ваш. Но это отличный трюк в разработке, когда вы хотите дать себе возможность прервать длинный цикл работы или способ удерживать клавишу shift для обхода части кода.

 Option Explicit Private Declare Function GetAsyncKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer Private Sub Command1_Click() Do Label1.Caption = Now() Label1.Refresh If WasKeyPressed(vbKeyEscape) Then Exit Do Loop Label1.Caption = "Exited loop successfully" End Sub Function WasKeyPressed(ByVal plVirtualKey As Long) As Boolean If (GetAsyncKeyState(plVirtualKey) And &H8000) Then WasKeyPressed = True End Function 

Документация для GetAsyncKeyState находится здесь:

http://msdn.microsoft.com/en-us/library/ms646301(VS.85).aspx

EDIT получается, что статья MSDN ошибочна, и техника НЕ РАБОТАЕТ 🙁

Вот статья об использовании компонента .NET BackgroundWorker для запуска задачи в другом streamе из VB6.

Вот довольно стандартная схема асинхронной фоновой обработки в VB6. (Например, это в книге Дэна Эпплмана и в образцах Microsoft VB6.) Вы создаете отдельный ActiveX EXE для выполнения работы: таким образом, работа выполняется автоматически в другом streamе в отдельном процессе (что означает, что вам не нужно беспокоиться о перетаскиваемые переменные).

  • Объект VB6 ActiveX EXE должен выставить событие CheckQuitDoStuff (). Это берет ByRef Boolean, называемый Quit.
  • Клиент вызывает StartDoStuff в объекте ActiveX EXE. Эта процедура запускает таймер по скрытой форме и немедленно возвращается . Это разблокирует вызывающий stream. Интервал таймера очень короткий, поэтому событие Timer срабатывает быстро.
  • Обработчик событий Timer отключает таймер, а затем снова возвращается к методу DoStuff объекта ActiveX. Это начинает длительную обработку.
  • Периодически метод DoStuff вызывает событие CheckQuitDoStuff. Обработчик события клиента проверяет специальный флаг и устанавливает Quit True, если это необходимо для прерывания. Затем DoStuff прерывает вычисление и возвращает раньше, если Quit is True.

Эта схема означает, что клиент фактически не должен быть многопоточным, так как вызывающий stream не блокируется, пока происходит «DoStuff». Трудная часть заключается в том, чтобы DoStuff поднимал события через соответствующие промежутки времени – слишком долго, и вы не можете уйти, когда захотите: слишком короткий, и вы замедляете DoStuff без необходимости. Кроме того, когда DoStuff завершает работу, он должен выгрузить скрытую форму.

Если DoStuff действительно сумеет получить все, что было сделано до того, как будет прервано, вы можете поднять другое событие, чтобы сообщить клиенту, что задание завершено.

  • Где я могу получить VB6 IDE
  • Назначение объектов в VB6
  • Обучение VB6
  • Является ли VB6 IDE для Windows 7/8/10 64-бит?
  • Разница между Visual Basic 6.0 и VBA
  • Как создать контрольные массивы в VB .NET
  • Ваши любимые инструменты и советы Visual Basic 6.0
  • В чем разница между Dim, Global, Public и Private в качестве модификаторов модульного поля?
  • чтение xml-файлов в vb6
  • Использование двоеточий для размещения двух операторов в одной строке в Visual Basic
  • GetWindowRect возвращает размер, включая «невидимые» границы
  • Interesting Posts

    Добавление объектов в пространство имен пакетов

    Как обеспечить локализованное описание с типом ошибки в Swift?

    Использование горячих клавиш VLC через командную строку

    Увидеть, нормально ли распределены данные в R

    Папки обновлений Windows (со странными именами) на диске C

    Asp.NET Web API – 405 – HTTP-глагол, используемый для доступа к этой странице, недопустим – как установить сопоставления обработчиков

    escape словарный ключ двойного кавычки при выполнении пункта println словаря в Swift

    XPath выбирает все элементы между двумя конкретными элементами

    Visual Studio действует странно. Как это исправить?

    Почему методы интерфейса C # не объявлены абстрактными или виртуальными?

    Что означает :: (двойной двоеточие) в пакетных файлах DOS?

    Интерфейс Android Alarm Clock

    Разница между репозиторием и уровнем обслуживания?

    Можно ли использовать сервер для игры?

    Добавление ключа в реестр

    Давайте будем гением компьютера.