InfinityJoe Ответов: 2

Vb.net получить "реальную" общую загрузку процессора так же, как диспетчер задач ?


Я долго искал этот вариант до 2017 года, но я думаю, что никто и ничто не дает намека на "реальное" значение общего использования процессора, как и диспетчер задач в VB.NET



Что я уже пробовал:

Вот какой метод я попробовал с несколькими предложениями в интернете
- счетчик производительности
- инструментарий WMI

случае например :
В диспетчере задач показано : ЦП-25%
затем при использовании как счетчика производительности, так и метода WMI с интервалом 1000 оба они просто показывали более низкое значение, чем в Диспетчере задач (почему ???)

Я думаю, что есть какой-то способ получить тот же результат, что и значение Диспетчера задач, может быть, просто получить весь список всех использований каждого потока и объединить их в одно значение для одной метки, например :
LblCpuUsage.text = CombinedAllCpuUsageOfEachThread.NextValue() - но я не знаю , как это сделать, так кто-нибудь знает, как это сделать ???

Примечание: Любой метод должен быть в порядке, пока он работает и такой же, как значение Диспетчера задач ( % ), и VB.NET код должен быть идеальным!

большое спасибо,
Джо

2 Ответов

Рейтинг:
1

Jochen Arndt

Для получения этой информации существует вспомогательная библиотека: помощник по данным производительности (см. Использование функций PDH для потребления данных счетчика (Windows)[^]).

Примеры Microsoft находятся на языке C, но есть также соответствующие функции VB (не .Net) :
Функции счетчиков производительности для Visual Basic (Windows)[^]

Английское имя счетчика для общего использования процессора - "\Processor(_Total)\% Processor Time", которое может быть передано в PdhAddEnglishCounter. При использовании Pdh[Vb]AddCounter вы должны передать локализованную строку.

Вызов PdhOpenQuery и PdhAdd[English]Counter один раз для настройки. Тогда называть PdhCollectQueryData периодически получать актуальные данные. Вызов PdhCloseQuery при выходе.


InfinityJoe

Привет, приятель, спасибо за ваш ценный ответ, просто рассмотрел ваши предложения, и это отличная точка запуска!, кстати, не могли бы вы дать какой-то намек на реальное использование кода этого вспомогательного метода Performance Data ?

Кстати, я почти уверен, что если этот метод может решить эту проблему (получить реальное использование процессора, как в Диспетчере задач), мы поможем многим людям, которые ищут его сейчас и когда-нибудь! особенно те, кто работает над проектом с использованием процессора reated (только на codeProject) :)

с нетерпением ждем дополнительной информации

Овации,
Джо

К вашему сведению: я заглядываю внутрь VB.NET код, чем C ( до тех пор, пока код C может быть легко преобразован, я думаю, что это должно быть хорошо, так как мы знаем, что некоторый код C не может быть легко преобразован в VB - наоборот)

Jochen Arndt

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

Я протестировал его с помощью приложения MFC C++, и оно показывает то же значение, что и диспетчер задач.

Пример в https://msdn.microsoft.com/en-us/library/windows/desktop/aa371886(v=vs.85). aspx показывает, как открыть встроенный диалог для выбора счетчика. Это может быть использовано для получения возможных строк.

Библиотека PDH - это всего лишь интерфейс для получения данных из операционной системы. Существует не так много документации, но Примеры C можно использовать, чтобы узнать, как это работает. Делать подобное в VB тогда не должно быть никаких проблем.

InfinityJoe

Спасибо за быстрый ответ mate и спасибо за повторную проверку его на MFC , это определенно дальнейший прогресс, когда этот метод действительно показал то же значение в диспетчере задач!, кстати, я пытался преобразовать его на vb, но, кажется, мне нужна какая-то информация от программиста C++ ниже :)

Овации,
Джо

Рейтинг:
0

InfinityJoe

Итак, вот моя грубая попытка преобразовать код C++ в VB, но, похоже, в нем было что-то отсутствующее, перечисленное ниже (выделено жирным шрифтом) :

1. Я думал, что это импорт оператора lib/dll в C++, так как же получить pdh.lib/dll или ссылаться на него на VB ?

#pragma comment(lib, "pdh.lib")


2. Вот этот "sizeof" всегда известно, что не имеет эквивалента в VB, так что какой-нибудь намек на это ?
ZeroMemory(&BrowseDlgData, sizeof(PDH_BROWSE_DLG_CONFIG));


3. что такое wprintf в C++ ? это то же самое, что и "консоль.writeline (...) или debug.метода WriteLine(...) ?
wprintf(...)


Любая помощь будет оценена по достоинству! :)

полный код:
Преобразовано из https://msdn.microsoft.com/en-us/library/windows/desktop/aa371886(v=против 85).aspx[^]

Imports System
Imports Microsoft.VisualBasic

Public Class PDHMonitor
    
'Declare
    Private Const SAMPLE_INTERVAL_MS As ULong = 1000
    Private Const BROWSE_DIALOG_CAPTION As String = "Select a counter to monitor."

    'C++ TO VB ? 
    #pragma comment(lib, "pdh.lib")

    Private Sub wmain()
        Dim Status As New PDH_STATUS()
        Dim Query As HQUERY = Nothing
        Dim Counter As New HCOUNTER()
        Dim DisplayValue As New PDH_FMT_COUNTERVALUE()
        Dim CounterType As UInteger
        Dim SampleTime As New SYSTEMTIME()
        Dim BrowseDlgData As New PDH_BROWSE_DLG_CONFIG()
        Dim CounterPathBuffer As New String(New Char(PDH_MAX_COUNTER_PATH - 1) {})

        'Create a query.
        Status = PdhOpenQuery(Nothing, Nothing, Query)

        If Status IsNot ERROR_SUCCESS Then
            wprintf(LvbLf & "PdhOpenQuery failed with status 0x%x.", Status)
            GoTo Cleanup
        End If

        'Initialize the browser dialog window settings.
        ZeroMemory(CounterPathBuffer, Len(CounterPathBuffer))

        'C++ TO VB equivalent of 'sizeof' ?
        ZeroMemory(BrowseDlgData, sizeof(PDH_BROWSE_DLG_CONFIG))

         With BrowseDlgData
            .bIncludeInstanceIndex = 0
            .bSingleCounterPerAdd = 1
            .bSingleCounterPerDialog = 1
            .bLocalCountersOnly = 0
            .bWildCardInstances = 1
            .bHideDetailBox = 1
            .bInitializePath = 0
            .bDisableMachineSelection = 0
            .bIncludeCostlyObjects = 0
            .bShowObjectBrowser = 0
            .hWndOwner = Nothing
            .szReturnPathBuffer = CounterPathBuffer
            .cchReturnPathLength = PDH_MAX_COUNTER_PATH
            .pCallBack = Nothing
            .dwCallBackArg = 0
            .CallBackStatus = ERROR_SUCCESS
            .dwDefaultDetailLevel = PERF_DETAIL_WIZARD
            .szDialogBoxCaption = BROWSE_DIALOG_CAPTION
        End With

        ' Display the counter browser window. The dialog is configured
        ' to return a single selection from the counter list.
        Status = PdhBrowseCounters(BrowseDlgData)

        If Status IsNot ERROR_SUCCESS Then
            If Status Is PDH_DIALOG_CANCELLED Then
                Console.Write(LvbLf & "Dialog canceled by user.")
            Else
                wprintf(LvbLf & "PdhBrowseCounters failed with status 0x%x.", Status)
            End If
            GoTo Cleanup
        ElseIf CounterPathBuffer.Length = 0 Then
            Console.Write(LvbLf & "User did not select any counter.")
            GoTo Cleanup
        Else
            wprintf(LvbLf & "Counter selected: %s" & vbLf, CounterPathBuffer)
        End If

        'Add the selected counter to the query.
        Status = PdhAddCounter(Query, CounterPathBuffer, 0, Counter)
        If Status IsNot ERROR_SUCCESS Then
            wprintf(LvbLf & "PdhAddCounter failed with status 0x%x.", Status)
            GoTo Cleanup
        End If

        ' Most counters require two sample values to display a formatted value.
        ' PDH stores the current sample value and the previously collected
        ' sample value. This call retrieves the first value that will be used
        ' by PdhGetFormattedCounterValue in the first iteration of the loop
        ' Note that this value is lost if the counter does not require two
        ' values to compute a displayable value.
        Status = PdhCollectQueryData(Query)
        If Status IsNot ERROR_SUCCESS Then
            wprintf(LvbLf & "PdhCollectQueryData failed with 0x%x." & vbLf, Status)
            GoTo Cleanup
        End If

        'Print counter values until a key is pressed.
        Do While Not _kbhit()

            Sleep(SAMPLE_INTERVAL_MS)
            GetLocalTime(SampleTime)
            Status = PdhCollectQueryData(Query)

            If Status IsNot ERROR_SUCCESS Then
                wprintf(LvbLf & "PdhCollectQueryData failed with status 0x%x.", Status)
            End If

            wprintf(LvbLf & """%2.2d/%2.2d/%4.4d %2.2d:%2.2d:%2.2d.%3.3d""", SampleTime.wMonth, SampleTime.wDay, SampleTime.wYear, SampleTime.wHour, SampleTime.wMinute, SampleTime.wSecond, SampleTime.wMilliseconds)

            'Compute a displayable value for the counter.
            Status = PdhGetFormattedCounterValue(Counter, PDH_FMT_DOUBLE, CounterType, DisplayValue)
            If Status IsNot ERROR_SUCCESS Then
                wprintf(LvbLf & "PdhGetFormattedCounterValue failed with status 0x%x.", Status)
                GoTo Cleanup
            End If

            Console.Write(",""{0:g20}""", DisplayValue.doubleValue)
        Loop

Cleanup:
        ' Close the query.
        If Query IsNot Nothing Then
            PdhCloseQuery(Query)
        End If
    End Sub
End Class


Richard Deeming

Если вы хотите обновить свой вопрос, Нажмите зеленую ссылку "улучшить вопрос" в нижней части вопроса и отредактируйте его.

НЕ опубликуйте свое обновление как "решение"!

InfinityJoe

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

Овации

Jaroslav Mitrovic

Привет, InfinityJoe.

У меня есть некоторые идеи по этому поводу, но я тихо не уверен, никогда не писал C++ (признался только дважды).

Я нашел это о комментарии #pragma:
"https://books.google.de/books?id=CbwYAAAAQBAJ&pg=PA295&lpg=PA295&dq=pragma+comment+to+vb&source=bl&ots=k3QIlHouHv&sig=USsi9pSYiW_-Ml4piYemv9ETbnQ&hl=de&sa=X&ved=0ahUKEwjVzp_xgOHYAhWKYlAKHfmyCd4q6aeimjab#v=onepage&q=pragma%20comment%20to%20vb&f=false"

Поэтому я думаю, что вы хотите использовать DLL в своем .Чистая правда? В codeproject есть много примеров импорта DLL.
Не так уж трудно это сделать.
Проблема заключается в управляемом и неуправляемом импорте Dll в VB.NET. Есть и обходные пути, но, похоже, здесь дело не в этом.

Таким образом, "#pragma" означает, что предполагается использование общей памяти...
"Комментарий" указывает на "секцию/часть" библиотеки DLL, которая будет использоваться в общей памяти...

"#ПРАГМА" сделать "это" в компиляторе с "comment(lib, то"пци.либерал")" так и с "той части" 'либерал' с 'пци.Либ'

хммм... не знаю, просто строю догадки.

Так что я бы не стал думать об этом, потому что вы будете использовать DLL, установив в проекте в IDE в любом случае ссылку? Я думаю, что это единственный способ сделать это с++.

Если вы можете получить доступ к библиотеке DLL и создать в ней что-то или использовать функцию a из библиотеки DLL, вам будет хорошо идти.

А еще эти штуковины с Wprint.

Вы правы, просто изучая код, это должно быть что-то вроде ".writeline"

wprintf(LvbLf &ампер; """%2.2 д/%2.2 д/%д 4.4 %2.2 д:%2.2 д:%2.2 д.%3.3 д""", SampleTime.wMonth, SampleTime.wDay, SampleTime.wYear, SampleTime.wHour, SampleTime.wMinute, SampleTime.wSecond, SampleTime.wMilliseconds)


Приставка.Напишите(",""{0:g20}""", DisplayValue.doubleValue)

Ты ведь это знаешь, правда?
Отлаживать.WriteLine("начало моей строки: {0} {1} некоторый заполняющий текст между вторым значением и последним значением {2}""", WhateverValue0, WhateverValue1, WhateverValue2)

Отлаживать.Напишите("мой результат процессора: {0:g20}" , MyCpuResult.Ценность}
Это просто значение в специальном форматировании, и кажется, что C++ делает это в стиле "я очень особенный и нечитаемый".

Для этого было бы лучше всего использовать DateTime.
Используйте "SampleTime" и каким - то образом преобразуйте его.
При необходимости сделайте функцию преобразования из "SampleTime" в Sample-DateTime.

от Microsoft:


Dim dateString, format As String
Dim result As Date
Dim provider As CultureInfo = CultureInfo.InvariantCulture

' Parse date-only value with invariant culture.
dateString = "06/15/2008"
format = "d"
Try
result = Date.ParseExact(dateString, format, provider)
Console.WriteLine("{0} converts to {1}.", dateString, result.ToString())
Catch e As FormatException
Console.WriteLine("{0} is not in the correct format.", dateString)
End Try


Так что просто используйте все "SampleTime.WhateverValues" и использовать их для создания экземпляра объекта DateTime.
А если "SampleTime.wMonth" имеет числовое значение, вы также идете в go. Вы можете передавать значения в качестве параметров для создания экземпляра DateTime.
Если "SampleTime.wMonth" представляет собой строку (и другие тоже) не использовать ".Метод Parse () функция" объекта datetime.

Также подумайте о том, чтобы использовать временные промежутки, в .NET они действительно Performate и оптимизированы для обработки TimeRelated Datastructures и делают als быстрые вычисления на них.
И самое лучшее из этого у него есть ".ToString()" метод, в котором вы можете передать выходной формат в коротком синтаксисе .("Я очень особенный и менее нечитабельный, чем та чепуха с++..."

никакого реального решения, но, может быть, намек...

c.u. Zui из Гамбурга