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

Вход: cam_frame-background, media_frame-foreground, media_frame_alpha - alpha. Выход: смешанный альфа-прозрачный. Если media_frame_alpha - IPL_DEPTH_8U, используйте «cv :: merge», потому что матрицы должны иметь равные размеры, размер, каналы. Работайте быстро, если opencv построит с помощью sse или avx. И быстрее, если использовать cv: GpuMat, должен иметь поддержку nvidia cuda и создавать opencv с cuda. ​​

inline cv::Mat frame_mix_alpha(cv::Mat &cam_frame,
 cv::Mat &media_frame,
 cv::Mat &media_frame_alpha)
{
    Mat suba = media_frame_alpha;
    //Mat alpha = cvCreateImage(media_frame_alpha.size(), IPL_DEPTH_8U, 1);
    //cvtColor(media_frame_alpha, alpha, CV_BGR2GRAY);

    //Mat suba;
    //Mat rgba[3] = { alpha, alpha, alpha };
    //merge(rgba, 3, suba);

    Mat subb = ~suba;

    //Mat mincam = min(cam_frame, suba);
    //Mat minmedia = min(media_frame, subb);
    //Mat result = (cam_frame - mincam) + (media_frame - minmedia);
    Mat result = (cam_frame - suba) + (media_frame - subb);

    return result;
}
21
задан MarkJ 12 August 2009 в 11:25
поделиться

8 ответов

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

, Если Вы помещаете DoEvents в свой основной цикл и находите, это замедляет обработку слишком много, попытайтесь назвать Windows API function GetQueueStatus (который намного быстрее, чем DoEvents) быстро определить, необходимо ли даже назвать 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
29
ответ дан Joel Spolsky 12 August 2009 в 11:25
поделиться

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

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

4
ответ дан Bob 12 August 2009 в 11:25
поделиться

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

Примечание, что это имеет действительно большой недостаток: это обнаружит, если пользователь поразит клавишу выхода в КАКОЕ-ЛИБО приложение - не просто Ваш. Но и это - большой прием в разработке, когда Вы хотите дать себе способ прервать длительный цикл или способ удержать клавишу 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 (По сравнению с 85) .aspx

4
ответ дан Shane Miskin 12 August 2009 в 11:25
поделиться

РЕДАКТИРОВАНИЕ это складывается , статья MSDN испорчена, и техника не РАБОТАЕТ : (

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

4
ответ дан Community 12 August 2009 в 11:25
поделиться

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

единственная вещь, которую можно сделать, называет DoEvents однажды для каждых 1 000 повторений или такого.

8
ответ дан GSerg 12 August 2009 в 11:25
поделиться
  • 1
    Тогда Вы wouldn' t потребность json_decode, Тогда Вы wouldn' t потребность [110], [111] уже был бы массив.POST['data'] уже был бы массив. – Rocket Hazmat 12 July 2012 в 17:01

"Для" цикла, работающего в потоке GUI? Если так, да, Вам будет нужен DoEvents. Можно хотеть использовать отдельный Поток, в этом случае DoEvents не требовался бы. можно сделать это в VB6 (не простой).

7
ответ дан TheSoftwareJedi 12 August 2009 в 11:25
поделиться
  • 1
    Дружественное напоминание, чтобы всегда проверить Ваши значения сообщения, бросающие их вокруг. – citizen conn 21 October 2013 в 01:55

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

4
ответ дан MusiGenesis 12 August 2009 в 11:25
поделиться

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

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

Эта схема означает, что клиенту на самом деле не нужно быть многопоточным, поскольку вызывающий поток не блокируется, пока выполняется "DoStuff". Сложная часть состоит в том, чтобы убедиться, что DoStuff инициирует события с подходящими интервалами - слишком долго, и вы не можете выйти, когда захотите: слишком короткое, и вы чрезмерно замедляете DoStuff. Кроме того, когда DoStuff завершает свою работу, он должен выгрузить скрытую форму.

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

4
ответ дан 29 November 2019 в 06:32
поделиться