Ich will einen eigenen Hardware Monitor für meine PC's erstellen und bin auf einen Thread vom Open Hardware Monitor gestoßen. Alles klappt super falls man nur eine Ausgabe über die Konsole haben will, aber sobald ein Element zb Label oder Progressbar angesteuert werden soll geht auf der Form gar nichts mehr... kein bewegen , schließen usw.
using OpenHardwareMonitor.Hardware;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace HwMonitor
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
public void GetSystemInfo()
{
var updateVisitor = new UpdateVisitor();
var computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature)
{
SetProgressBar(computer.Hardware[i].Sensors[j].Name, (float)computer.Hardware[i].Sensors[j].Value);
//Console.WriteLine($"{computer.Hardware[i].Sensors[j].Name}: {computer.Hardware[i].Sensors[j].Value}\u00B0C\r");
}
}
}
}
computer.Close();
}
public void SetProgressBar(string name, float value)
{
switch(name)
{
case "CPU Core #1":
progressBar1.Value = (int)value;
Thread.Sleep(100);
label1.Text = $"{Math.Round(value, 1)}%";
Thread.Sleep(100);
break;
}
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
GetSystemInfo();
Thread.Sleep(1000);
}
}
}
}
Hallo,
bist Du Dir sicher, dass Du im Click-Event vom Button eine Endlosschleife haben möchtest?
Edit:
Wenn man Dein Thread.Sleep() mit der Schleife gegen z.B. einen Timer mit einen Intervall von 1000 tauscht, sähe es (vom Code her alleine schon) um einiges besser aus.
Ja ich hatte es mit einem Timer vorher aber, ich habe es gewechselt weil nicht einmal die Form sich geöffnet hatte.
Trotz des Timers kann reagiert meine WinForm ca nur alle paar sekunden auf einen befehl wie schließen oder bewegen etc.. Kann man dass irgendwie verbessern weil so ist es nicht wirklich nutzbar
Keine Full Quotes
[Hinweis] Wie poste ich richtig?
Kennst du schon [FAQ] Warum blockiert mein GUI?
Du darfst niemals im Hauptthread (UI-Thread) die Anwendung warten lassen.
Ja dass ist mir nicht neu aber habe nie damit gearbeitet.
Kannst du mir bitte helfen damit dass es funktioniert bin neu auf dem Gebiet?
Keine Full Quotes
[Hinweis] Wie poste ich richtig?
Kannst du mir bitte helfen damit dass es funktioniert bin neu auf dem Gebiet?
z.B. starte deine Methode in einem Thread und aktualisiere dein Progressbar über delegate.
**:::
Ja danke dafür aber wie soll ich dass hier machen:?
Keine Full Quotes
[Hinweis] Wie poste ich richtig?
Ja danke dafür aber wie soll ich dass hier machen:? https://www.codeproject.com/Articles/449594/Progress-Bars-Threads-Windows-Forms-and-You
**:::
Danke aber dass habe ich mir auch schon angeschaut aber egal was ich versuche es laggt immer noch rum ... Kannst du mir zeigen wie ich es richtig implementiere in meinen Code? Würde mir viel mehr helfen als der Beitrag.
Keine Full Quotes
[Hinweis] Wie poste ich richtig?
Dann zeige noch mal deinen aktuellen Code mit dem Timer.
Dass wäre einfach mit dem Timer (1000ms).
Ich habe die versuche mit task etc rausgemacht weil es nicht funktioniert hatte.
using OpenHardwareMonitor.Hardware;
using System;
using System.Windows.Forms;
namespace HwMonitor
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{
}
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
public void GetSystemInfo()
{
var updateVisitor = new UpdateVisitor();
var computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature)
{
SetProgressBar(computer.Hardware[i].Sensors[j].Name, (float)computer.Hardware[i].Sensors[j].Value);
}
}
}
}
computer.Close();
}
public void SetProgressBar(string name, float value)
{
switch (name)
{
case "CPU Core #1":
progressBar1.Value = (int)value;
label1.Text = $"{Math.Round(value, 1)}%";
break;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
GetSystemInfo();
}
}
}
So sieht der Code doch ganz gut aus. Oder gibt es noch Probleme damit?
So sieht es zwar gut aus aber wenn ich zb alle 4 Kerne abfrage und nicht nur 1 kann man die form nur alle paar sekunden ziehen /minimieren und maximieren etc und kein Button reagiert mehr.
Musst das Abfragen eben in einen Task auslagern.
Im Endeffekt ist es das: [FAQ] Warum blockiert mein GUI?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Musst das Abfragen eben in einen Task auslagern.
Im Endeffekt ist es das:
>
Ändert sich nichts ist immer noch nicht nutzbar die Form. Progressbar / Label ändert sich richtig aber nur lade Zeichen über der Form und keine Reaktion auf befehle (zb Button).
using OpenHardwareMonitor.Hardware;
using System;
using System.Threading;
using System.Windows.Forms;
namespace HwMonitor
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
Thread systemInfo;
private void Form3_Load(object sender, EventArgs e)
{
systemInfo = new Thread(new ThreadStart(GetSystemInfo));
systemInfo.Start();
}
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
public void GetSystemInfo()
{
try
{
while (true)
{
var updateVisitor = new UpdateVisitor();
var computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature)
{
if (progressBar1.InvokeRequired)
{
progressBar1.Invoke(new Action(GetSystemInfo));
}
else
{
SetProgressBar(computer.Hardware[i].Sensors[j].Name, (float)computer.Hardware[i].Sensors[j].Value);
}
}
}
}
}
computer.Close();
Thread.Sleep(100);
}
}
catch(ThreadAbortException ex)
{
Console.WriteLine(ex.Message);
}
}
public void SetProgressBar(string name, float value)
{
switch (name)
{
case "CPU Core #1":
progressBar1.Value = (int)value;
label1.Text = $"{Math.Round(value, 1)}%";
break;
}
}
private void button1_Click(object sender, EventArgs e)
{
systemInfo.Abort();
Console.WriteLine("Thread has been stopped!");
}
}
}
Etwas unsauberer Code; aber aus dem Thread heraus dürfte die UI nicht mehr blockieren oder Anzeichen davon haben.
Die Endlosschleife ist natürlich total unnötig und sollte periodisch erfolgen.
[Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Etwas unsauberer Code; aber aus dem Thread heraus dürfte die UI nicht mehr blockieren oder Anzeichen davon haben.
Die Endlosschleife ist natürlich total unnötig und sollte periodisch erfolgen.
Warum ist die Endlosschleife total unnötig? Ich will ja die Aktuellen werte haben jede x sekunden oder ms?
Der Thread klappt aber nur ohne schleife.
Was soll denn der rekursive Aufruf
progressBar1.Invoke(new Action(GetSystemInfo));
?
Du mußt (nur) SetProgressBar
per Invoke
aufrufen (evtl. in eine eigene Methode auslagern).
PS: Mußt du denn UpdateVisitor
sowie Computer
jedesmal wieder in der Schleife neu erzeugen? Besser wäre doch, diese nur einmalig zu erzeugen und dann nur noch deren Methoden periodisch aufzurufen.
Reaper_97, bitte unterlass endlich die Full Quotes.
[Hinweis] Wie poste ich richtig?
Keine Lust quasi jeden Post von Dir editieren zu müssen.
Danke. 👍
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Es waren nicht immer full quotes aber wenn du meinst.
Da leider keine passende Antwort bisher gekommen ist hatte ich mich den ganzen mittag schlau gemacht und eine passende Lösung gefunden mit weniger Code.
Ich hoffe Du verstehst wenigstens den Code, den Du von irgendwo kopierst.
Den Code hier hast offenbar selbst nicht verstanden =)
Die Rekursion, die Th69 nannte, gehört da natürlich nicht hin.
Wäre aber durch ein selbstständiges Debuggen ( [Artikel] Debugger: Wie verwende ich den von Visual Studio? ) aufgefallen.
Der Thread klappt aber nur ohne schleife.
Ist natürlich totaler Humbug. Man kann problemlos eine Method periodisch starten, die dann einen Task (oder wenn wirklich notwendig einen Thread) ausführt.
Mit Reactive Extensions ist das in zwei Zeilen gemacht.
Aber ja, den Code hier kann man extrem schlanker gestalten - das ist korrekt.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich verstehe alles, nur dass problem waren die threads. Mit denen habe ich bisher noch nicht viel gearbeitet weil es nicht nötig war bei den meisten Sachen. Und davon abgesehen ich habe nicht irgendein Code kopiert oder sonst was. Ich habe nur online eine funktion wieder gesehen die ich vergessen hatte und dass Problem behoben hat was dein Kommentar nicht konnte wie man sieht.
Und wegen dem x gehört nicht hin stimmte auch nicht ganz weil ich einfach dass alte kopiert hatte wo es noch nicht richtig abgeändert war lol. Davon abgesehen mache ich dass alles als Hobby und Arbeite damit nicht.
Und wieder ein Full Quote!
[Hinweis] Wie poste ich richtig?
Bin mir gerade nicht sicher, ob der Edit Deine Absicht war, dass Du dort quasi den halben Thread nachträglich als Fullquote eingefügt hast, nachdem ich Deinen erneuten Fullquote entfernt habe....
Ich war aber neugierig, was das NuGet Paket OpenHardwareMonitor so bietet.
Daher habe ich Deinen Code kurz als Basis genommen und mit den Tipps hier im Thread korrigiert bzw erweitert.
Deine Symptome kann ich nachvollziehen aber mit den Tipps hier im Thread lösen:
computer.Accept blockiert die UI, sodass diese sich nicht ordentlich verschieben lässt. Standardproblem von [FAQ] Warum blockiert mein GUI?
Gesamthema gelöst anhand der Tipps hier im Forum bzw. in den Antworten. 👍
Es ist das eine, wenn man es nicht hinbekommen, weil man noch recht neu ist - aber dann muss man sagen, wo genau es hängt.
Die Aussage
Da leider keine passende Antwort bisher gekommen ist
ist jedoch einfach eine Ohrfeige für die Leute, die hier versucht haben Dir zu helfen.
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenHardwareMonitor.Hardware;
namespace WindowsFormsApp1
{
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor)
{
}
public void VisitParameter(IParameter parameter)
{
}
}
public static class ControlExtensions
{
public static void UIThread(this Control source, Action body)
{
if (source.InvokeRequired)
{
source.BeginInvoke(body);
}
else
{
body.Invoke();
}
}
}
public partial class Form1 : Form
{
private IDisposable _subscription;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (_subscription is null)
{
_subscription = Observable.Interval(TimeSpan.FromSeconds(1))
.Subscribe(async x => await ReadSystemInfoAsync());
}
}
private void button2_Click(object sender, EventArgs e)
{
_subscription?.Dispose();
_subscription = null;
}
public async Task ReadSystemInfoAsync()
{
await Task.Run(() =>
{
var updateVisitor = new UpdateVisitor();
var computer = new Computer();
try
{
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
foreach (IHardware t in computer.Hardware)
{
if (t.HardwareType != HardwareType.CPU) continue;
foreach (ISensor t1 in t.Sensors)
{
if (t1.SensorType != SensorType.Load) continue;
SetProgressBar(t1.Name, t1.Value);
}
}
}
catch (Exception e)
{
// Mach irgendwas mit Exceptions
}
finally
{
computer.Close();
}
});
}
public void SetProgressBar(string name, float? load)
{
float value = load.GetValueOrDefault(0);
switch (name)
{
case "CPU Core #1":
this.UIThread(() =>
{
progressBar1.Value = (int)value;
label1.Text = $"{Math.Round(value, 1)}%";
});
break;
}
}
}
}
PS: OpenHardwareMonitor mag offenbar meine CPU nicht; daher statt der Temperatur die Auslastung als Sensor genommen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Nur mein Eindruck beim Lesen des Themas hier:
Es macht keinen Sinn Code nur zu kopieren ohne ihn zu verstehen und noch schlimmer - zu glauben/behaupten ihn zu verstehen, aber durch seine Antworten zeigen, dass man davon noch meilenweit entfernt ist.
Ansonsten wurde zum Thema/Problem selber ja schon alles gesagt ([FAQ] Warum blockiert mein GUI?)
Ich habe gerade in Sicherheitslücke in vorinstallierter Analyse-Software macht HP-Rechner unsicher gelesen, daß es wohl einen Safety-Bug im "Open Hardware Monitor" gibt.
Leider ist das Projekt Open Hardware Monitor wohl seit fast 3 Jahren nicht mehr gepflegt - du solltest also vorsichtig sein.