Auslesen der CPU-Kerne funktioniert nicht richtig

  • Allgemein

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von Jonas Jelonek.

    Auslesen der CPU-Kerne funktioniert nicht richtig

    Hallo liebe Community,
    ich hätte eine rasche Frage undzwar will ich die CPU Kerne in einem neuen Thread auslesen und zu einer Combobox hinzufügen.

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Ermittelt die Anzahl der CPU-Kerne.
    3. ''' </summary>
    4. ''' <remarks>Bei einem Fehler wird der Wert -1 zurückgegeben.</remarks>
    5. Public Shared Function GetNumberOfCores() As Integer
    6. Try
    7. Dim searcher As New ManagementObjectSearcher( _
    8. "root\CIMV2", _
    9. "SELECT * FROM Win32_Processor")
    10. Dim strCores As String = String.Empty
    11. For Each queryObj As ManagementObject In searcher.Get()
    12. strCores = queryObj("NumberOfCores").ToString
    13. Return Integer.Parse(strCores)
    14. Next
    15. Catch err As ManagementException
    16. Return -1
    17. End Try
    18. End Function
    19. ''' <summary>
    20. ''' Ermittelt die Anzahl der CPU-Kerne und weißt diese der Combobox zu.
    21. ''' </summary>
    22. Private Sub GetAndSetCoreCount()
    23. For int As Integer = 0 To Gather.SystemInfo.GetNumberOfCores
    24. Me.BeginInvoke(Sub() cboxCPUCount.Items.Add(int.ToString))
    25. Next
    26. End Sub
    27. 'Aufruf im Form-Load Event
    28. 'Systeminformationen ermitteln.
    29. tThread = New Thread(New ThreadStart(AddressOf GetAndSetCoreCount))
    30. tThread.Start()


    Es funktioniert auch perfekt bis zum 4 Kern.
    Jedoch fügt er dann einen 5. Nicht vorhandenen Kern 5 mal zur Combobox hinzu.

    Die Funktion GetNumberOfCores selbst funktioniert einwandfrei.
    Anscheinend habe ich irgendetwas an der For-Schleife falsch gemacht.


    Danke im Vorraus.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Warum For int [...] = 0 To [...].GetNumberOfCores? Müsste die Null nicht durch eine 1 ersetzt werden? Denn wenn du von 0 hochzählst, kriegst du zum Beispiel bei 4 Cored die Zahlen 0, 1, 2, 3, 4 raus.
    OK. Klingt logisch, jedoch wurde nie Core-0 Hinzugefügt.
    Jetzt hat es sich minimal verbesser. In der Combobox befinden sich nun: "1,2,3,4,5,5,5,5" Anstatt fünf Fünfer.

    @Artentus
    Das ist ja egal. Kommt auf das Selbe.
    MsgBox(Gather.SystemInfo.GetNumberOfCores.ToString)
    Gibt mir auch "4" zurück.

    Edit://
    Mit Environment.ProcessorCount passiert genau das Selbe wie oben beschrieben.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Eben getestet:

    VB.NET-Quellcode

    1. Dim list As New List(Of Integer)
    2. Dim max_cpu As Integer = Environment.ProcessorCount
    3. For i As Integer = 1 To max_cpu
    4. list.Add(i)
    5. Next


    So schreibt er bei mir alles von 1 - 8 in die Liste.
    Meinst du mich?!

    hier nochma ne kleine ConsolenApplication:

    VB.NET-Quellcode

    1. Module Module1
    2. Sub Main()
    3. For i As Integer = 1 To Environment.ProcessorCount
    4. Console.WriteLine("Core {0}", i.ToString())
    5. Next
    6. Console.ReadLine()
    7. End Sub
    8. End Module


    Funktioniert auf beiden Rechnern und aufn VPS.
    Funktioniert wesentlich besser.
    Abgesehen davon dass jetzt das 5. Item noch "(Auflistung)" ist.
    Aber das werd ich mir morgen ansehen, sollte nicht zu schwer zu beheben sein.
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    @n1nja
    Nein, du hast ja gar keinen Lambda-Audruck in deinem Code. ;)

    Nur mal um zu begründen, warum das nicht gut ist:
    Lambda-Ausdrücke, die lokale Variablen verwenden, werden vom Compiler in eine extra Klasse gekapselt, in der sich die Funktion und eine Referenz auf diese Variable befindet, damit gewährleistet werden kann, dass der Wert der Variablen verfügbar ist. Wenn du diese Variable nun ständig über eine Schleife änderst, und mehrere Lambda-Ausdrücke darauf zugreifen, dann ändert sich auch immer die Referenz. Wir der Lambda-Ausdruck also erst nach dem Ändern der Variablen ausgeführt, dann hat die Variable einen womöglich unbeabsichtigeten Wert, und der Lambda-Ausdruck daher ein unvorhergesehenes Ergebnis. Dadurch, dass du hier mir Threads rumhantierst, kann sowas ganz leicht eintreten, und dann hast du den Salat.

    Gather schrieb:

    Anscheinend habe ich irgendetwas an der For-Schleife falsch gemacht.
    die Null-basierung der Arrays bei .NET iwie falsch umgesetzt. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe diesen Thread durchgelesen und mein Interesse reduziert sich nun auf die Geschichte mit Lamda-Funktionen.

    Noch nie gehört.... also gegoogelt.

    ...Gut ich glaube zwar nun (dank des Threads mit anschließendem googln) ein bisschen zu wissen was gemeint ist mit: "Lamda Funktionen", aber in Bezug auf diesen Thread check ich's wieder ned so recht.

    Eine Lamda ist ja auch definiert mit Function oder Sub. Auf welchen Post und Lamdafunktion genau beziehst du dich also, @Artentus?
    LG, Hinti
    @Hinti:
    Hier in diesem Thema gibt es gar keine Lamba-Funktion.
    Er bezog sich jedoch auf n1njas Post.

    @All
    Ich bin noch in der Schule, deswegen kann ich nichts ausprobieren,
    jedoch wüsstet Ihr auf die Schnelle wieso es folgendes Problem gibt:

    Gather schrieb:

    Abgesehen davon dass jetzt das 5. Item noch "(Auflistung)" ist.

    Heißt die Combobox-Itmes sind derzeit:
    "1,2,3,4,(Auflistung)"
    Und ja es steht wortwörtlich (Auflistung) in der Combobox.


    Edit://
    Ich hab ganz einfach den Code von n1nja übernommen,
    da mir dieser sehr vernüpftig scheint ^^

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Ermittelt die Anzahl der CPU-Kerne und weißt diese der Combobox zu.
    3. ''' </summary>
    4. Private Sub GetAndSetCoreCount()
    5. Dim list As New List(Of Integer)
    6. Dim max_cpu As Integer = Environment.ProcessorCount
    7. list.Clear()
    8. For i As Integer = 1 To max_cpu
    9. list.Add(i)
    10. Next
    11. Me.BeginInvoke(Sub() cboxCPUCount.Items.Add(list))
    12. End Sub
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Gather“ ()

    @Hinti
    @Gather
    Nope, ich bezog mich auf den Startpost. In Zeile 26 befindet sich ein Lambda-Ausdruck, und zwar in exakt dieser von mir weiter oben angesprochenen ungünstigen Position.
    Mit dem Code von n1nja tritt dieses Problem nicht mehr auf, denn der Threadübergreifende Vorgang und die Schleife liegen nicht mehr so im Zusammenhang mit dem Lambda-Ausdruck, dass was schief laufen könnte.
    @Artentus:
    Ah verstehe!

    Zum Environment.ProcessorCount:
    Ist vom Prinzip her egal, denno löst das mein Problem nicht ^^
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Habe deinen Code mal zum Funktionieren gebracht

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Ermittelt die Anzahl der CPU-Kerne.
    3. ''' </summary>
    4. ''' <remarks>Bei einem Fehler wird der Wert -1 zurückgegeben.</remarks>
    5. Public Shared Function GetNumberOfCores() As Integer
    6. Try
    7. Dim searcher As New ManagementObjectSearcher( _
    8. "root\CIMV2", _
    9. "SELECT * FROM Win32_Processor")
    10. Dim strCores As String = String.Empty
    11. For Each queryObj As ManagementObject In searcher.Get()
    12. strCores = queryObj("NumberOfCores").ToString
    13. Return Integer.Parse(strCores)
    14. Next
    15. Catch err As ManagementException
    16. Return -1
    17. End Try
    18. End Function
    19. ''' <summary>
    20. ''' Ermittelt die Anzahl der CPU-Kerne und weißt diese der Combobox zu.
    21. ''' </summary>
    22. Private Sub GetAndSetCoreCount()
    23. Dim cores As Integer = GetNumberOfCores()
    24. For int As Integer = 0 To cores
    25. ComboBox1.Items.Add(int.ToString)
    26. Next
    27. End Sub
    @Jonas Jelonek:
    Dir ist bewusst, dass dies was 1zu1 der Code ist denn ich am Anfang verwende.
    Herauskommt (obviously, da es fast genau der gleiche Code ist) das Anfangsproblem:
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!