Цикл с наименьшей нагрузкой на ЦП

Этот цикл очень загружает ЦП:

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
        Case $control1
            Func1()
        Case $control2
            Func2()
    EndSwitch
WEnd

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


person Levi    schedule 27.09.2013    source источник
comment
Предоставьте полный код, который воспроизводит проблему. Именно для этого кода я написал рабочий скрипт и не заметил никаких проблем. Вполне возможно, что если $control1 или $control2 равно 0, у вас возникнут проблемы, или если Func1 или Func2 сильно нагружают ЦП, или если есть вещи, работающие в фоновом режиме с использованием функций Adlib.   -  person Matt    schedule 27.09.2013


Ответы (2)


Я столкнулся с этой проблемой, используя Switch/Case. Я думал, что усложнение кода и изменение на Select/Case снизит нагрузку на ЦП. использование. В конечном итоге я загнал скрипт в цикл Do/Until. .

Этот отрывок из сценария, который находится на панели задач и всегда работает. Пользователи взаимодействуют, щелкая и выбирая в контекстном меню, которое я создал. Это запускает соответствующую функцию.

While 1
    Do
        $msg = TrayGetMsg()
    Until $msg <> 0
    Select
        Case $msg = $ItemDeviceModel
            DeviceModel()
        Case $msg = $ItemSerial
            SerialNumber()
        Case $msg = $ExitItem
            Exit
    EndSelect
WEnd

В этом примере сценарий зацикливается на быстром и простом выполнении Do/Until (которое ожидает, пока пользователь не щелкнет значок приложения). После разрыва цикла запускается Select/Case.

Переключите свой код с помощью:

While 1
    Do
        $msg = GUIGetMsg()
    Until $msg <> 0
    Switch $msg
        Case $GUI_EVENT_CLOSE
            GUIDelete()
            Exit
        Case $control1
            Func1()
        Case $control2
            Func2()
    EndSwitch
WEnd
person Colyn1337    schedule 27.09.2013

Как указал разработчик AutoIt, " mouse move" является вторым наиболее часто вызываемым сообщением, поэтому вы можете также предварительно отфильтровать его после сообщения "0".

#include <GUIConstantsEx.au3>

While 1
    Switch GUIGetMsg()
        Case 0, $GUI_EVENT_MOUSEMOVE
            ContinueLoop
        Case $control1
            Func1()
        Case $control2
            Func2()
    EndSwitch
WEnd


При попытке просмотреть несколько источников сообщений, а именно GUIGetMsg() и TrayGetMsg(), я столкнулся с трудностями из-за ContinueLoop.

Но решение на самом деле простое, не сокращайте цикл, а просто отключите переключатель (помните, что разрывы неявны в AutoIt):

#include <GUIConstantsEx.au3>

While 1
    Switch GUIGetMsg()
        Case 0, $GUI_EVENT_MOUSEMOVE
            ; break
        Case $control1
            Func1()
        Case $control2
            Func2()
    EndSwitch

    Switch TrayGetMsg()
        Case 0, $GUI_EVENT_MOUSEMOVE
            ; break
        Case $control3
            Func3()
        Case $control4
            Func4()
    EndSwitch
WEnd


(только что проверил, TrayGetMsg() тоже отправляет $GUI_EVENT_MOUSEMOVE сообщений)

person Gras Double    schedule 29.12.2016