Страница: 1 | 2 |
|
Вопрос: Нагрузка на проц в циклах
|
Добавлено: 09.04.10 10:08
|
|
Автор вопроса: Spiritsun
|
Всем привет. У меня самый простой вопрос, может кто знает. Почему циклы так грузят проц и как этого избежать? У меня 2 ядра и 1-ый под 100%. Вот пример:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Do
Loop
End Sub
End Class
Вместо Do пытался вставить goto, както поэксперементировать, результат тотже. Самже я использую подобные циклы для проверок GetAsyncKeyState. Api функцию Sleep, чтобы делать задержки в этих циклах пытаюсь избегать, т.к. отрицательно влияет на работу в самих циклах. Вот как она выглядит:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer)
Ответить
|
Номер ответа: 3 Автор ответа: Spiritsun
Вопросов: 15 Ответов: 44
|
Профиль | | #3
|
Добавлено: 09.04.10 14:14
|
Да не, особо не волнует вопрос про распределения на потоки, но почитать бы хотел. Есть ссылка? А вот нагрузка на проц - проблема серъезная и наверняка частая, думаю тоже сталкивались, может и не обращали внимания. Гляньте в диспетчере задачь как работает ваша программа, если раньше такое использовали. Распишу подробней чем тут занимаюсь, может есть какаято альтернатива решающая мою проблему.
Запускается форма с единственной клавишей старта. При нажатии сворачивается. Далее идёт анализ нажатия клавиши. Этот анализ при свёрнутом окне получается совершить только функцией api GetAsyncKeyState и производится он в бесконечном замкнутом цикле. После нажатия вызывается определенная процедура, являющаяся основой программы. Я также использую таймер и там тоже проверяю другие нажатия клавиши тойже функцией, являющиеся более важными, которые могут повлиять на ход выполнения основной процедуры (Про таймер, наверное зря сказал, наверное особо тут не играет роль, вас только запутал). Вот пример:
- Imports System
- Imports System.IO
- Imports System.Globalization
- Imports System.Drawing.Imaging
- Imports System.Windows.Forms
- Imports System.Windows
- Public Class Main
- Private Declare Function GetAsyncKeyState% Lib "user32" (ByVal vKey As Long)
- ...
- Private Sub Старт_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Старт.Click
- Do
- System.Windows.Forms.Application.DoEvents()
- If GetAsyncKeyState(&H25) And GetAsyncKeyState(&H11) Then
- ...
- End If
- Loop
- End Sub
- Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
- If GetAsyncKeyState(&H27) And GetAsyncKeyState(&H11) Then
- End
- End If
- End Sub
- ...
- End Class
Ответить
|
Номер ответа: 7 Автор ответа: Spiritsun
Вопросов: 15 Ответов: 44
|
Профиль | | #7
|
Добавлено: 09.04.10 17:08
|
AWP, дело не в вызове api функция миллионы раз. Смотри предыдущий пример с пустым do loop. Только таймером не могу воспользоваться, объясню почему. В теле проги после нажатия на Старт объявляются объекты bitmap и их размер зависит от параметров, загруженных с файла. Объект image и bitmap невозможно передать в процедуру Timer, а после и в др процедуры, что можно сделать из основного модуля. Вот пример как я делаю:
- Private Sub Старт_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Старт.Click
- ...
- Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
- Dim tabpic As New Bitmap(1280, 1024)
- Dim gtabpic As Graphics = Graphics.FromImage(tabpic)
- CreateTablo(tabpic, gtabpic)
- redr(tabpic, gtabpic)
- ...
- Do
- System.Windows.Forms.Application.DoEvents()
- If GetAsyncKeyState(&H25) And GetAsyncKeyState(&H11) Then
- If tabshow Then
- redr(tabpic, gtabpic)
- End If
- End If
- ...
- Loop
- End Sub
- Public Sub redr(ByVal tabpic As Bitmap, ByVal gtabpic As Graphics)
- ...
- End Sub
- ...
- End Class
В этом случае я правда могу сделать tabpic глобальной, но если размеры Bitmap(1280, 1024) брать с файла настроек или определением тек разрешения соотв оператором, то только так. Есть др варианты?
А теперь представь, что подобные цыклы еще присутствуют в ожидании чегото и в итоге тормоза, что жуть. Может эту проблему исправили в новой версии vba этого года? Проверял ктонить?
Executioner, спасибо за наводку, только не понятно как мне это может помочь. Можеж объяснить, пжалста?
Ответить
|
Номер ответа: 11 Автор ответа: Spiritsun
Вопросов: 15 Ответов: 44
|
Профиль | | #11
|
Добавлено: 09.04.10 22:21
|
Хорошо. Чтобы долго не придумывать, вот над чем щаз голову ломаю, могите тут реализовать hook. В vba 2008 не запускается. Возможно нужно дополнительно подключать какойто dll. Как и какой не знаю. Есть инфа, но не разобрался
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.ru/winui/winui/windowsuserinterface/windowing/hooks/usinghooks.htm#installing_releasing
- Public Class Form1
-
- Private Sub Form_Load()
-
-
-
-
- hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, 0, 0)
- End Sub
- Private Sub Form_Unload(ByVal Cancel As Integer)
-
- UnhookWindowsHookEx(hHook)
- End Sub
- End Class
-
- Module Module1
- Public Const WH_KEYBOARD = 2
- Public Const VK_SHIFT = &H10
- Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, ByVal lParam As Object) As Long
- Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
- Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
- Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
- Public hHook As Long
- Public Function KeyboardProc(ByVal idHook As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
-
- If idHook < 0 Then
-
- KeyboardProc = CallNextHookEx(hHook, idHook, wParam, lParam)
- Else
-
- If (GetKeyState(VK_SHIFT) And &HF0000000) And wParam = Asc("S") Then
-
- MsgBox("Shift-S pressed ...")
- End If
-
- KeyboardProc = CallNextHookEx(hHook, idHook, wParam, lParam)
- End If
- End Function
- End Module
Еще при редактировании пишет ошибку на "AddressOf KeyboardProc" - невозможно преобразовать выражение AddressOf в Long, т.к. Long не яв-ся типом делегата. По сути прога должна при нажатии Shift-S вывести сообщение.
Ответить
|
Страница: 1 | 2 |
Поиск по форуму