Why the loop is taking so long and so slow? - c#

I created a new class for the testing:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenHardwareMonitor.Hardware;
using System.Diagnostics;
using DannyGeneral;
using System.Windows.Forms;
using System.Threading;
using System.Management;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
namespace HardwareMonitoring
{
class CpuUsages
{
public static string processes;
public static string cputest()
{
PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
var unused = cpuCounter.NextValue(); // first call will always return 0
System.Threading.Thread.Sleep(1000); // wait a second, then try again
//Console.WriteLine("Cpu usage: " + cpuCounter.NextValue() + "%");
processes = "Cpu usage: " + cpuCounter.NextValue() + "%";
return processes;
}
}
}
Then in form1 i added a new timer set it to 1000ms enable it when running the program and inside the timer tick event i did:
private void timer3_Tick(object sender, EventArgs e)
{
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
CpuUsages.cputest();
cpuusage = CpuUsages.processes;
label26.Text = cpuusage;
}
}
This way it's working very slow take a long time to make the loop foreach.
In general i wanted to loop over each running process and get it's cpuusage.
But if i remove the foreach loop like this:
private void timer3_Tick(object sender, EventArgs e)
{
Process[] processes = Process.GetProcesses();
CpuUsages.cputest();
cpuusage = CpuUsages.processes;
label26.Text = cpuusage;
}
Then it will work fast i will see in label26 the cpuusage updating eavery second.
The problem is that it will show the cpuusage for only on process.
What can i do to solve it ?
In general i wanted to create automatic number of labels for each process in the list and display each process cpuusage. But it's so slow and take so long when i use the foreach loop.
Is there any way to solve it ?

This:
foreach (Process process in processes)
{
CpuUsages.cputest();
cpuusage = CpuUsages.processes;
label26.Text = cpuusage;
}
will make your program sleeps for 1 second * (number of processes running on your machine). No wonder the foreach loop is slow.
Remove those Sleep calls, and have your loop running in another Thread, avoiding slowing down the User interface.
Also I don't see why you are iterating over the processes returned by Process.GetProcesses() : you are not using them.

Related

Simple explorer.exe restart script in C#

I was just looking for a simple script in which checks if explorer.exe is running. If it is, then kill it and restart it. However, if it is not running, then start it.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
public partial class App
{
public static void Main()
{
Process[] prcChecker = Process.GetProcessesByName("explorer");
if (prcChecker.Length > 0)
{
foreach (Process p in prcChecker)
{
p.Kill();
}
}
else if (prcChecker.Length == 0)
Process.Start("explorer.exe");
}
}
I haven´t tested it but maybe it´s something like this you´re looking for
//to kill a process
foreach (var process in Process.GetProcessesByName("whatever"))
{
process.Kill();
}
//to start
Process.Start("explorer.exe", "");

How can I determine the SATA channel for a given disk?

Using DISKPART command line utility, I can get something called a "Location path" which appears to give me what I need, you can view this by using the command detail disk after selecting one of your disks in diskpart.
It appears I can get this information programatically via this class: MSFT_Disk
I am unsure about how to get an instance of this class. I have a few examples of using a ManagementObjectSearcher for WMI classes but that method is not working for me, I am also unsure of MSFT_Disk's availability in Windows 7 as the page mentions that this is for Windows 8.
Does anyone know of a good way to get SATA channel information or the "location path" of a disk?
If you want to not require Windows 8, I believe WMI is the way to go:
using System;
using System.Linq;
using System.Management;
namespace DiskScanPOC
{
class Program
{
static void Main()
{
var managementScope = new ManagementScope();
//get disk drives
var query = new ObjectQuery("select * from Win32_DiskDrive");
var searcher = new ManagementObjectSearcher(managementScope, query);
var oReturnCollection = searcher.Get();
//List all properties available, in case the below isn't what you want.
var colList = oReturnCollection.Cast<ManagementObject>().First();
foreach (var property in colList.Properties)
{
Console.WriteLine("Property: {0} = {1}", property.Name, property.Value);
}
//loop through found drives and write out info
foreach (ManagementObject oReturn in oReturnCollection)
{
Console.WriteLine("Name : " + oReturn["Name"]);
Console.WriteLine("Target Id: " + oReturn["SCSITargetId"]);
Console.WriteLine("Port: " + oReturn["SCSIPort"]);
}
Console.Read();
}
}
}
I didn't crack open my case to verify the SATA port numbers, but the above app looks like it gives reasonable results on my machine with 3 SATA hard drives.
If you want to get the location path, SetupDiGetDeviceRegistryProperty is the function you're looking for. Set the property value to SPDRP_LOCATION_INFORMATION.
I'm assuming you already know how to enumerate devices to get the DeviceInfoSet and DeviceInfoData.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Management;
namespace Hard_Disk_Interface
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCheck_Click(object sender, EventArgs e)
{
WqlObjectQuery q = new WqlObjectQuery("SELECT * FROM Win32_IDEController");
ManagementObjectSearcher res = new ManagementObjectSearcher(q);
lblHDDChanels.Text = string.Empty;
foreach (ManagementObject o in res.Get())
{
string Caption = o["Caption"].ToString();
lblHDDChanels.Text += Caption + "\n\n";
if (Caption.Contains("Serial"))
{
lblInterface.Text = "S-ATA";
}
}
}
}
}
Note: First Add the reference of System.Management.dll of .net freamwork 4.0

Argument Out of range Exception when insert element into list

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> ul = new List<string>();
Process[] procs = Process.GetProcesses();
int u = 0;
foreach (Process proc in procs)
{
ul[u] = proc.ProcessName;
u++;
}
}
}
}
I want to move each process name into my arraylist each time loop executed but i'm getting outofbound Exception. please provide some sample codes. thanks in advance...
You can't access an element in List that hasn't been set yet. Use the .Add() function.
foreach (Process proc in procs)
{
ul.Add(proc.ProcessName);
}
Try using the .Add() function, like this:
static void Main(string[] args)
{
List<string> ul = new List<string>();
foreach (Process proc in Process.GetProcesses())
{
ul.Add(proc.ProcessName);
}
}
A List<> when created, has a default size, and in your code elements get added until that size is full (at which point the next 'insert' fails. The add() method checks to see if this size limit is no longer enough and increases the size of the list when required.
This code also eliminates the need for a couple of your variables.

Is there a tool that allows easy exporting of messages from a message queue (MSMQ)?

I am currently working on batch processing application using MSMQ in C#. In the application design, I have an error queue containing XML messages using the ActiveXFormatter. I know that I can write an application to write these error messages to text files or database tables.
Are there other pre-built tools available allowing you to export messages to variety of formats (i.e. text files, database tables, etc.)? I am just looking for best practices.
Ok. I found the solution of writing code to be really easy. Here's my reference solution.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Messaging;
namespace ExportMSMQMessagesToFiles
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void btnExportTextFiles_Click(object sender, EventArgs e)
{
//Setup MSMQ using path from user...
MessageQueue q = new MessageQueue(txtMSMQ.Text);
//Setup formatter... Whatever you want!?
q.Formatter = new ActiveXMessageFormatter();
// Loop over all messages and write them to a file... (in this case XML)
MessageEnumerator msgEnum = q.GetMessageEnumerator2();
int k = 0;
while (msgEnum.MoveNext())
{
System.Messaging.Message msg = msgEnum.Current;
string fileName = this.txtFileLocation.Text + "\\" + k + ".xml";
System.IO.File.WriteAllText(fileName, msg.Body.ToString());
k++;
}
MessageBox.Show("All done!");
}
}
}

C#: Why is my Process that is running Java.exe working perfectly, but the window isn't returning ANY output?

I created a Process that is targeted to the Java.exe file. The process should run a Java.jar server file, and continue to run giving output feedback until the server crashed or I forcefully close it down. Everything works fine.. the server is running.. and when I set UseShellExecute to True I can see the black CMD window returning all the output. But when I set it to false and redirect the output... the Window is completely blank ( the server is still running though ) and the OutputDataReceived event doesn't fire at all ( I think I got it to once but that was when I closed the window it seemed the args was empty ) and as far as I can see StandardOutput.ReadToEnd() isnt returning anything either. Why is this Process not returning any Output feedback?? Here is my code:
gameServerProcess = new Process();
gameServerProcess.StartInfo.UseShellExecute = false;
gameServerProcess.StartInfo.RedirectStandardOutput = true;
gameServerProcess.StartInfo.RedirectStandardInput = true;
gameServerProcess.EnableRaisingEvents = true;
gameServerProcess.Exited += new EventHandler(gameServer_WindowExit);
window = new ServerWindow();
gameServerProcess.OutputDataReceived += new DataReceivedEventHandler(window.server_recievedOutputStream);
window.Show();
gameServerProcess.StartInfo.FileName = #"D:\Program Files\Java\jdk1.6.0_12\bin\java.exe";
gameServerProcess.StartInfo.WorkingDirectory = #"D:\Users\Zack\Desktop\ServerFiles\gameserver";
gameServerProcess.StartInfo.Arguments = #"-Xmx1024m -cp ./../libs/*;l2jserver.jar net.sf.l2j.gameserver.GameServer";
gameServerProcess.Start();
gameServerProcess.BeginOutputReadLine();
And my 'window' form class code which should receive the DataReceivedEventArgs with the output data:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace MWRemoteServer
{
public partial class ServerWindow : Form
{
private delegate void WriteOutputDelegate(string output);
private WriteOutputDelegate writeOutput;
public ServerWindow()
{
InitializeComponent();
logBox.BackColor = Color.White;
logBox.ForeColor = Color.Black;
writeOutput = new WriteOutputDelegate(write);
}
public void server_recievedOutputStream(object sender, DataReceivedEventArgs args)
{
MessageBox.Show("Called window output!");
if (args.Data != null)
{
BeginInvoke(writeOutput, new object[] { args.Data.ToString() });
}
}
private void write(string output)
{
logBox.AppendText(output + Environment.NewLine);
}
}
}
Again the process works completely fine and with the UseShellExecute set to true I can see it is providing all information I need to grab. But when I set that to false its blank and I cant seem to grab any output data!
Thank you so much in advance... I've been at this for hours and hours...
Are you sure it writes to stdout? Have you tried checking stderr? (RedirectStandardError/StandardError/ErrorDataReceived/BeginErrorReadLine).
If it writes directly to the display buffer (instead of stderr/stdout) then it might not be possible without a lot of work.

Categories

Resources