Why im getting all the time InvalidOperationException? - c#

I know what does it mean but i don't understand why i'm getting it.
In my class constructor i did:
namespace HM
{
class Core
{
public static Form1 form1;
Process[] pname;
private static List<float?> cpuSensorValues = new List<float?>();
private static List<float?> gpuSensorValues = new List<float?>();
Computer myComputer;
Computer computer;
public Core(Form1 f)
{
form1 = f;
myComputer = new Computer();
myComputer.CPUEnabled = true;
myComputer.FanControllerEnabled = true;
myComputer.MainboardEnabled = true;
myComputer.Open();
computer = new Computer();
computer.Open();
computer.GPUEnabled = true;
OpenHardwareMonitor.Hardware.ISensor isss;
Hardwares hwsd;
OpenHardwareMonitor.Hardware.ISensor ist;
pname = Process.GetProcessesByName("BFBC2Game");
}
I added this:
pname = Process.GetProcessesByName("BFBC2Game");
And when the game is running i see using a breakpoint that pname wontain one index that is the game process. And im sure to run first the game then the program.
Then i have a method in the class i call it with a timer in Form1 that get write to a log file the temeperature of the GPU Video Card.
This part was working good untill i added this pname process.
if (gpuSensorValues.Count == 30 && sensor.Value >= (float)numericupdown)
{
float a = ComputeStats(gpuSensorValues).Item1;
float b = ComputeStats(gpuSensorValues).Item2;
float c = ComputeStats(gpuSensorValues).Item3;
Logger.Write("********************************");
Logger.Write("GPU Minimum Temperature Is ===> " + a);
Logger.Write("GPU Maximum Temperature Is ===> " + b);
Logger.Write("GPU Average Temperature Is ===> " + c);
Logger.Write("********************************" + Environment.NewLine);
gpuSensorValues = new List<float?>();
pname.ToList().ForEach(p => p.Kill());
}
I added this :
pname.ToList().ForEach(p => p.Kill());
I wanted that if the temperature for example was 123c then kill/close/shut down the game at once ! Instead it's not writing to the logger file the temperature anymore and it's never kill the process but writing to the log file the exception message:
3/5/2014--4:10 AM ==> There was an exception: System.InvalidOperationException: No process is associated with this object.
at System.Diagnostics.Process.EnsureState(State state)
at System.Diagnostics.Process.EnsureState(State state)
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.Kill()
at HardwareMonitoring.Core.gpuView(Boolean pause, List`1 myData, Nullable`1 myGpuTemp, Button b1, Decimal numericupdown) in d:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Core.cs:line 172
This is the complete method code if needed:
public float? gpuView(bool pause, List<string> myData, float? myGpuTemp, Button b1, decimal numericupdown)
{
try
{
if (pause == true)
{
}
else
{
foreach (var hardwareItem in computer.Hardware)
{
if (form1.videoCardType("ati", "nvidia") == true)
{
HardwareType htype = HardwareType.GpuNvidia;
if (hardwareItem.HardwareType == htype)
{
foreach (var sensor in hardwareItem.Sensors)
{
if (sensor.SensorType == SensorType.Temperature)
{
sensor.Hardware.Update();
if (sensor.Value.ToString().Length > 0)
{
/* else if (UpdatingLabel(sensor.Value.ToString(), label16.Text.Substring(0, label16.Text.Length - 1)))
{
// Label8 = GpuText;
}*/
//myData = new List<string>();
//this.Invoke(new Action(() => data = new List<string>()));
if (!form1.IsDisposed)
{
form1.Invoke(new Action(() => myData.Add("Gpu Temeprature --- " + sensor.Value.ToString())));
}
//this.Invoke(new Action(() => listBox1.DataSource = null));
//this.Invoke(new Action(() => listBox1.DataSource = data));
//form1.Invoke(new Action(() => lb1.DataSource = myData));
//sensor.Value.ToString() + "c";
myGpuTemp = sensor.Value;
//label8.Visible = true;
}
//if (sensor.Value > 60)
//{
gpuSensorValues.Add(sensor.Value);
if (gpuSensorValues.Count == 30 && sensor.Value >= (float)numericupdown)
{
float a = ComputeStats(gpuSensorValues).Item1;
float b = ComputeStats(gpuSensorValues).Item2;
float c = ComputeStats(gpuSensorValues).Item3;
Logger.Write("********************************");
Logger.Write("GPU Minimum Temperature Is ===> " + a);
Logger.Write("GPU Maximum Temperature Is ===> " + b);
Logger.Write("GPU Average Temperature Is ===> " + c);
Logger.Write("********************************" + Environment.NewLine);
gpuSensorValues = new List<float?>();
pname.ToList().ForEach(p => p.Kill());
}
b1.Enabled = true;
//}
//form1.Select();
}
}
}
}
else
{
HardwareType htype = HardwareType.GpuAti;
if (hardwareItem.HardwareType == htype)
{
foreach (var sensor in hardwareItem.Sensors)
{
if (sensor.SensorType == SensorType.Temperature)
{
sensor.Hardware.Update();
if (sensor.Value.ToString().Length > 0)
{
myGpuTemp = sensor.Value;
//label8.Visible = true;
}
if (sensor.Value > 60)
{
Logger.Write("The Current Ati GPU Temperature Is ===> " + sensor.Value);
b1.Enabled = true;
}
form1.Select();
}
}
}
}
}
}
}
catch (Exception err)
{
Logger.Write("There was an exception: " + err.ToString());
}
return myGpuTemp;
}
Line 172 is:
//form1.Select();
Just empty line nothing to do there.

The docs for Process.Kill() show that it can raise an InvalidOperationException if the process is not running.
Maybe try: pname.Where(p => !p.HasExited).ToList().ForEach(p => p.Kill());

The problem is that one or more of the instances in your pname list aren't in the state you expect. As pointed out in another answer this could be because the process isn't running. Also, one of the references could be null. To prevent the exception try adding a where clause like the following;
pname.ToList().Where(p != null && !p.HasExited).ForEach(p => p.Kill());
I'm not familiar with the Process class so I'm not entirely sure what you'll want to use for that second condition in the Where but that should give you the idea. This will just filter out instances in the list that would cause the error before calling Kill().

The only problem i can see in your code is you are not clearing the pname object. If the pname has reference to a process that is no longer running, you will get this exception. I recommend to get fresh list of process when you want to stop it. Replace the following line
pname.ToList().ForEach(p => p.Kill());
with
pname = Process.GetProcessesByName("BFBC2Game");
pname.ToList().ForEach(p => p.Kill());

Related

Any way to simplify comparing lists of Processes?

I was just curious if there was a simplified way to write this bit of code, or more efficient.
I want to wait for a new notepad.exe to exist, add that process to a list of processes or list of process ids only if it is not already in the list, also remove any processes in that list that do not exist anymore. Then repeat in an endless loop.
public static List<int> Clients = new List<int>();
while(true)
{
foreach (int r in Clients)
if (!ProcessExists(r))
{
Clients.Remove(r);
Console.WriteLine(r + " was removed.");
break;
}
bool check = false;
Process[] initial = Process.GetProcessesByName("notepad");
foreach (Process i in initial)
{
foreach(int r in Clients)
{
if (i.Id == r)
{
check = true;
}
}
if (check == false)
{
Clients.Add(i.Id);
Console.WriteLine(i.Id + " was added.");
}
check = false;
}
Thread.Sleep(250);
}
private static bool ProcessExists(int id)
{
return Process.GetProcessesByName("notepad").Any(x => x.Id == id);
}
The first loop that take care of deletion can be simpler using Linq:
Clients.RemoveAll(p => !ProcessExists(p));
Or this way, to keep the log:
Clients.RemoveAll(p => {
if (!ProcessExists(p)) {
Console.WriteLine(p + " was removed.");
return true;
}
return false;
});
For the second loop, you can use Contains() method of the List<> class:
Process[] initial = Process.GetProcessesByName("notepad");
foreach (Process i in initial)
{
if (!Clients.Contains(i.Id))
{
Clients.Add(i.Id);
Console.WriteLine(i.Id + " was added.");
}
}

Linq Or IEnumerable taking Long to run when using Parallel.ForEach [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have an application that reads a csv (200 mb).
var lines = File.ReadLines(file).ToList();
The csv stores pricing information and has around 500k records in it.
The code snippet below when calling StoreValues takes around 18 seconds.
Is there a way to speed this up ?
distinctMarketIds = 54 int values
The lines collection will have 500k lines and each line [0] has marketId which im matching.
IEnumerable<string[]> newList = (lines.Where(t => distinctMarketIds.Contains(t.Split(',')[0]))
.Select(t => t.Split(',')));
log.Info(("Time Taken To Get Filtered Prices " + elapsed.Elapsed.TotalSeconds +" seconds."));
StoreValues(newList, file); //store the prices
log.Info(("Time Taken To Store Prices " + elapsed.Elapsed.TotalSeconds + " seconds."));
The Store value Method uses Parallel.ForEach
Parallel.ForEach(finalLines, new ParallelOptions { MaxDegreeOfParallelism = MaxThreads }, (line) =>
{
});
I cannot seem to find why it would take 18 seconds to go through this loop.
I have tested on another machine with similar specs and it takes 2.5 seconds for StoreValue Method
#region LoadPriceDataFromCsvFile
public int LoadPriceDataFromCsvFile(string filename, string[] marketIdList, int maxThreads)
{
MaxThreads = maxThreads;
int filteredRows = 0;
string[] files = Directory.GetFiles(filename, "*.csv");
elapsed.Start();
log.InfoFormat("Total Csv files to Scan {0}",files.Length);
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = MaxThreads }, (file) =>
{
try
{
log.InfoFormat("About to Scan File {0}", file);
ScanCsvFilesAndGetPrices(file);
}
catch (System.OutOfMemoryException e)
{
log.Info(e);
}
catch (Exception e)
{
log.Info(e);
}
});
return PriceCollection.Count;
}
#endregion
#region ScanCsvFilesAndGetPrices
private void ScanCsvFilesAndGetPrices(string file)
{
try
{
log.Info(("Time Taken " + elapsed.Elapsed.TotalSeconds + " seconds."));
var lines = File.ReadLines(file).ToList();
log.Info(("Time Taken To Read csv " + elapsed.Elapsed.TotalSeconds + " seconds."));
if (lines.Any())
{
log.Info(("Time Taken To Read Any " + elapsed.Elapsed.TotalSeconds + " seconds."));
var firstLine = lines.ElementAt(1); // This is the First Line with Headers
log.Info(("Time Taken To Read First Line " + elapsed.Elapsed.TotalSeconds + " seconds."));
var lastLine = lines.Last(); // This is the Last line in the csv file
log.Info(("Time Taken To Read Last Line " + elapsed.Elapsed.TotalSeconds + " seconds."));
var header = lines.First().Split(',');
log.Info(("Time Taken To Split Header Line " + elapsed.Elapsed.TotalSeconds + " seconds."));
GetIndexOfFields(header);
log.Info(("Time Taken To Read Header " + elapsed.Elapsed.TotalSeconds + " seconds."));
// Get the Publish Date Time
if (PublishedDatetime_Index != -1)
{
var fLine = firstLine.Split(',');
var lLine = lastLine.Split(',');
var firstLineDatetime = (fLine[PublishedDatetime_Index].Contains("+"))? fLine[PublishedDatetime_Index].Remove(fLine[PublishedDatetime_Index].IndexOf("+",StringComparison.Ordinal)): fLine[PublishedDatetime_Index];
var publishDateTimeFirstLine =FileNameGenerator.GetCorrectTime(Convert.ToDateTime(firstLineDatetime));
string lastLineDatetime = (lLine[PublishedDatetime_Index].Contains("+"))? lLine[PublishedDatetime_Index].Remove(lLine[PublishedDatetime_Index].IndexOf("+",StringComparison.Ordinal)): lLine[PublishedDatetime_Index];
var publishDateTimeLastLine =FileNameGenerator.GetCorrectTime(Convert.ToDateTime(lastLineDatetime));
// check if the order execution date time of any order lieas between the date time of first and last line of csv so we can add that csv to our filtered list
string[] distinctMarketIds = OrderEntityColection.FindAll(obj =>obj.OrderLastChangeDateTimeUtc >= publishDateTimeFirstLine &&obj.OrderLastChangeDateTimeUtc <= publishDateTimeLastLine).Select(obj => obj.MarketId.ToString())
.Distinct()
.ToArray();
log.InfoFormat("Total Markets Identified {0}",distinctMarketIds.Length);
List<OrderEntity> foundOrdersList = OrderEntityColection.FindAll(obj =>obj.OrderLastChangeDateTimeUtc >= publishDateTimeFirstLine &&obj.OrderLastChangeDateTimeUtc <= publishDateTimeLastLine);
lock (FoundOrdersList)
{
FoundOrdersList.AddRange(foundOrdersList);
}
log.InfoFormat("Total Orders Identified {0}", FoundOrdersList.Count());
log.Info(("Time Taken To Read Execution Times and Market " + elapsed.Elapsed.TotalSeconds +" seconds."));
if (distinctMarketIds.Length != 0)
{
IEnumerable<string[]> newList =
(lines.Where(
t => distinctMarketIds.Contains(t.Split(',')[0]))
.Select(t => t.Split(','))
);
log.Info(("Time Taken To Get Filtered Prices " + elapsed.Elapsed.TotalSeconds +" seconds."));
// this is taking longer than expected. Somthing to do with IEnumerable<string[]>
StoreValues(newList, file); //store the prices
log.Info(("Time Taken To Store Prices " + elapsed.Elapsed.TotalSeconds + " seconds."));
}
}
}
}
catch (Exception e)
{
log.Info(e);
}
}
#endregion
#region GetIndexOfFields
// These are the fields we want to Look for from the headers and accordingly get their location
private void GetIndexOfFields(IEnumerable<string> lineHeader)
{
int index = 0;
foreach (var column in lineHeader)
{
if (column == "MarketId")
{
MarketId_Index= index;
}
if (column == "Bid")
{
Bid_Index = index; ;
}
if (column == "Ask")
{
Ask_Index = index;
}
if (column == "Mid")
{
Mid_Index = index;
}
if (column == "Is_Indicative")
{
Is_Indicative_Index = index;
}
if (column == "Price_Engine")
{
Price_Engine_Index = index;
}
if (column == "PublishedDatetime")
{
PublishedDatetime_Index = index;
}
if (column == "Market_Is_Open")
{
Market_Is_Open_Index = index;
}
if (column == "AuditId")
{
AuditId_Index = index;
}
if (column == "Row_Update_Version")
{
Row_Update_Version_Index = index;
}
if (column == "DontPublish")
{
DontPublish_Index = index; ;
}
index++;
}
}
#endregion
#region StoreValues
private void StoreValues(IEnumerable<string[]> finalLines, string file)
{
log.InfoFormat("total Finel Lines Sent for Storing {0}", finalLines.Count());
Parallel.ForEach(finalLines, new ParallelOptions { MaxDegreeOfParallelism = MaxThreads }, (line) =>
{
var prices = new Prices();
// the code that you want to measure comes here
var datetime = (line[PublishedDatetime_Index].Contains("+")) ? line[PublishedDatetime_Index].Remove(line[PublishedDatetime_Index].IndexOf("+", StringComparison.Ordinal)) : line[PublishedDatetime_Index];
if (!IsNullOrEmpty(datetime))
{
prices.PublishedDatetime = Convert.ToDateTime(datetime);
}
if (!IsNullOrEmpty(line[MarketId_Index]))
{
prices.MarketId = Convert.ToInt32(line[MarketId_Index]);
}
if (!IsNullOrEmpty(line[Bid_Index]))
{
prices.Bid = Convert.ToDecimal(line[Bid_Index]);
}
if (!IsNullOrEmpty(line[Ask_Index]))
{
prices.Ask = Convert.ToDecimal(line[Ask_Index]);
}
if (!IsNullOrEmpty(line[Mid_Index]))
{
prices.Mid = Convert.ToDecimal(line[Mid_Index]);
}
if (!IsNullOrEmpty(line[Is_Indicative_Index]))
{
prices.Is_Indicative = Convert.ToBoolean(line[Is_Indicative_Index]);
}
else
{
prices.Is_Indicative = false;
}
if (!IsNullOrEmpty(line[Price_Engine_Index]))
{
prices.Price_Engine = Convert.ToString(line[Price_Engine_Index]);
}
if (!IsNullOrEmpty(line[Market_Is_Open_Index]))
{
prices.Market_Is_Open = line[Market_Is_Open_Index] == "1";
}
if (!IsNullOrEmpty(line[AuditId_Index]))
{
prices.AuditId = Convert.ToString(line[AuditId_Index]);
}
if (!IsNullOrEmpty(line[Row_Update_Version_Index]))
{
prices.Row_Update_Version = Convert.ToString(line[Row_Update_Version_Index]);
}
if (!IsNullOrEmpty(line[DontPublish_Index]))
{
if (DontPublish_Index != 0)
{
prices.DontPublish = line[DontPublish_Index] == "1";
}
}
prices.SbProdFile = file;
lock (PriceCollection)
{
PriceCollection.Add(prices);
}
});
}
I don't see how Parallel.ForEach could help to improve performance when you need to process a single file
Don't use File.ReadLines(file).ToList(), either use ReadAllLines if you want all lines in memory or use ReadLines if you want to process the lines one after another
Why do you split the line multiple times?
Use a HashSet<string> for distinctMarketIds:
This should be more efficient:
var marketIdSet = new HashSet<string>(OrderEntityColection.FindAll(obj =>obj.OrderLastChangeDateTimeUtc >= publishDateTimeFirstLine &&obj.OrderLastChangeDateTimeUtc <= publishDateTimeLastLine).Select(obj => obj.MarketId.ToString()));
IEnumerable<string[]> allFields = File.ReadLines(file)
.Select(line => line.Split(','))
.Where(arr => marketIdSet.Contains(arr[0]));
Note that due to deferred execution of Select and Where this is just a query, it is yet not executed. So whenever you will use allFields you will execute this query again. So it's a good idea to create a collection, f.e. with allFields.ToList() which you pass to StoreValues:
StoreValues(allFields.ToList(), file); //store the prices
If you pass a collection you could really benefit from using Parallel.ForEach in StoreValues.
static void Main()
{
//var lines = File.ReadLines(file).ToList();
// this is just a fast generation for sample data
var lines = Enumerable.Range(0, 500000)
.Select(i => string.Join(",", i % 7, i, i & 2))
.ToList();
// HashSet will work as an indexed store and will match faster in your loop
var distinctMarketIds = new HashSet<string>{
"0", "2", "3", "5"
};
// Do this if you are to use the method syntax instead of the query syntax
// var newList = lines.Select(l=>l.Split(','))
// .Where(ps=>distinctMarketIds.Contains(ps[0]));
var newList = from l in lines
// this will parse the string once versus twice as you were doing before
let ps = l.Split(',')
where distinctMarketIds.Contains(ps[0])
select ps;
// can't see the content of your `StoreValues` method but writing to a
// file in parallel will never work as expected.
using (var stream = new StreamWriter("outfile.txt"))
foreach (var l in newList)
stream.WriteLine(string.Join(";", l));
}

An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll during calling recursive function

// code execute infinite and giving me error as unhanded exception of type 'System.StackOverflowException////
//default declaration //
Hashtable ht = new Hashtable(); // for store pagerank during recursion i have used hash table
DBML.Dbml_UploadDataContext objdbcontext = new DBML.Dbml_UploadDataContext(TDBConvertion.Properties.Settings.Default.MY_DBConnectionString); // this is DataContext of my DBML and all tables have primary key and foreign key in it.
//method for calling recursive function //
public string calculatepagerank()
{
double damp = 0.85;
double output=0;
objdbcontext.Connection.Open();
string stroutput = "";
foreach (var item in objdbcontext.Engine_Directories) // for all ids i want to calculate pr
{
output = pagerank(item.ID, objdbcontext.Engine_Links_Inlinks.Where(w => w.LinkID == item.ID).ToList(), objdbcontext.Engine_linkcounts.Where(x => x.ID == item.ID).FirstOrDefault().OutLinks.Value,damp);
stroutput = stroutput + ",Iteration::" + i + ",ID=" + item.ID + ",pagerank=" + output.ToString() + "\n";
}
ht.Clear();
objdbcontext.Connection.Close();
return stroutput;
}
/// recursive function //
public double pagerank(Int64 intId,List<DBML.Engine_Links_Inlink> listInlinksID,Int64 intoutlinkcount,double dumpingfactor)
{
double count = 0;
double o = 0;
foreach(var item in listInlinksID)
{
Int64 outlinkcount=1;
if( objdbcontext.Engine_linkcounts.Where(x => x.ID == item.InlinksID).FirstOrDefault()!=null)
{
Int64 outc = objdbcontext.Engine_linkcounts.Where(x => x.ID == item.InlinksID).FirstOrDefault().OutLinks.Value;
outlinkcount=( outc !=0)?outc:1 ;
}
if (!ht.ContainsKey(item.InlinksID))
{
o = pagerank(item.InlinksID.Value,objdbcontext.Engine_Links_Inlinks.Where(w => w.LinkID == item.InlinksID).ToList(), outlinkcount, dumpingfactor);
ht.Add(item.InlinksID.Value, o);
count = count + o;
}
else
{
count = count + Convert.ToDouble(ht[item.InlinksID].ToString());
}
}
return dumpingfactor + dumpingfactor * (count/intoutlinkcount);
}
Well .NET have not infinity-size stack. By default it's 1MB only. Execute this code in new thread with larger stack size(second argument for "Thread" constructor), or use loops instead of recursion.
Could you possibly refactor the following piece of code?
if (!ht.ContainsKey(item.InlinksID))
{
o = pagerank(item.InlinksID.Value,objdbcontext.Engine_Links_Inlinks.Where(w => w.LinkID == item.InlinksID).ToList(), outlinkcount, dumpingfactor);
ht.Add(item.InlinksID.Value, o);
count = count + o;
}
Instead of recursively calling pagerank, why don't you do take the code and add use coroutines?

How do i get the cpu fan speed using the OpenHardwareMonitor lib?

I referenced my project with OpenHardwareMonitor.dll
And then created new class with this code:
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;
namespace HardwareMonitoring
{
class Core
{
public static Form1 form1;
private static List<float?> cpuSensorValues = new List<float?>();
private static List<float?> gpuSensorValues = new List<float?>();
Computer myComputer;
Computer computer;
public Core(Form1 f)
{
form1 = f;
myComputer = new Computer();
myComputer.CPUEnabled = true;
myComputer.Open();
computer = new Computer();
computer.Open();
computer.GPUEnabled = true;
}
public float? cpuView(bool pause , CpuTemperature cpuTemp , Form1 f1 , List<string> myData , float? myCpuTemp , Button b1)
{
try
{
if (pause == true)
{
}
else
{
Trace.WriteLine("");
foreach (var hardwareItem in myComputer.Hardware)
{
if (hardwareItem.HardwareType == HardwareType.CPU)
{
hardwareItem.Update();
foreach (IHardware subHardware in hardwareItem.SubHardware)
subHardware.Update();
foreach (var sensor in hardwareItem.Sensors)
{
cpuTemp.SetValue("sensor", sensor.Value.ToString());
if (sensor.SensorType == SensorType.Fan)//Temperature)
{
sensor.Hardware.Update();
cpuTemp.GetValue("sensor", sensor.Value.ToString());
if (!f1.IsDisposed)
{
Thread.Sleep(1000);
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
}
myCpuTemp = sensor.Value;
//if (sensor.Value > 60)
//{
cpuSensorValues.Add(sensor.Value);
if (cpuSensorValues.Count == 300)
{
float a = ComputeStats(cpuSensorValues).Item1;
float b = ComputeStats(cpuSensorValues).Item2;
float c = ComputeStats(cpuSensorValues).Item3;
Logger.Write("********************************");
Logger.Write("CPU Minimum Temperature Is ===> " + a);
Logger.Write("CPU Maximum Temperature Is ===> " + b);
Logger.Write("CPU Average Temperature Is ===> " + c);
Logger.Write("********************************" + Environment.NewLine);
cpuSensorValues = new List<float?>();
}
b1.Enabled = true;
//}
break;
}
}
}
}
}
}
catch(Exception err)
{
Logger.Write("There was an exception: " + err.ToString());
}
return myCpuTemp;
}
On the line:
if (sensor.SensorType == SensorType.Fan)//Temperature)
If i'm using the Temperature it's working fine and showing the temperature.
But once i change it to Fan the SensorType never == to the Fan
And if i'm running the original openhardwaremonitor program it's showing all the stuff even the cpu fan speed.
So why in my code it's not working ?
EDIT**
Forgot to mention that in Form1 at the top i have:
private CpuTemperature cpu;
Then in the constructor:
cpu = new CpuTemperature(new Dictionary<string, string>
{
{ "/intelcpu/0/temperature/0/values", "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iu6//MH37x79i9/+NX6N3/TJm9/5f/01fw1+fosnv+A/+OlfS37/jZ/s/Lpv9fff6Ml/NTef/yZPnozc5679b+i193//TQZ+/w2Dd+P9/sZeX/67v/GTf/b3iP3u4/ObBL//73+i+f039+D8Zk/+xz/e/P6beu2TQZju8yH8f6OgzcvPv/U3/Rb8+z/0f/9b/+yfaOn8079X6fr6Cws7ln/iHzNwflPv99/wyS/+xY4+v/evcJ+733+jJ5//Cw7/4ndy9Im3+U2e/Fbnrk31C93vrt/fyPvdb+N//hsF7/4/AQAA//9NLZZ8WAIAAA==" },
{ "/intelcpu/0/load/0/values", "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iu6//MH37x79i9++mpwcv/md/9df89egZ/xX/ym/5y/4D37618Lv7ya//u+58+u+5d9/z7/5t/w9/6u5fP5bH/6av+eTkXyefXxp26ONaf/v/dG/sf39D/rvnv4e5vc/0IP56/waK/vuHzf5I38P8/tv+mv8Rbb9f0pwTF9/zr/1X9vP/8I//+/6Pf7Z30N+/zdf/HX29zd/859q4aCNP5b//U+U3/+7f+zXOjZwfqvDX/V7/o9/vPz+a1G/pv0f+fGlhfk7eZ//N3/0v28//5X0u/n8Cxq7+f1X/tHft20A5x8a/W5/02+BP36Nf+j/nv8XfzrT+c2//Ob4p3+vktvUhNs/+xcWikP6e/4T/5jS5M8/sL8vP/5ff49f/Ivl9//sHzv6PX/vXyG//9R/94/9HuZ34P/5vyC//3W/5e/1exa/k+Bw4bUBnU2bP4Xg/1bn0uafeTH6PatfKL//N3/0t2y/gG9+/8+IzqYNxmU+/+jwX7afY67/nwAAAP//GYSA31gCAAA=" },
});
Maybe there should be something like this for the FAN of the cpu but i couldn't find any.
So i wonder how they use it in the original openhwardwaremonitor.
Tried to search in the source code : http://open-hardware-monitor.googlecode.com/svn/trunk/GUI/
But i didn't find how to get the cpu/gpu fans speed.
For anybody still struggling with this, you first have to enable the mainboard in your OpenHardwareMonitor.Hardware.Computer object:
Computer computerHardware = new Computer();
computerHardware.MainboardEnabled = true;
You then have to search 2 hardware layers deep.
By this I mean:
foreach (var hardware in computerHardware.Hardware)
{
// This will be in the mainboard
foreach (var subhardware in hardware.SubHardware)
{
// This will be in the SuperIO
subhardware.Update();
if (subhardware.Sensors.Length > 0) // Index out of bounds check
{
foreach (var sensor in subhardware.Sensors)
{
// Look for the main fan sensor
if (sensor.SensorType == SensorType.Fan && sensor.Name.Equals("Fan #1", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("CPU Fan Speed:" + Convert.ToString((int)(float)sensor.Value) + " RPM");
}
}
}
}
}
It is very important that you have the subhardware.update(); call in there, otherwise you will only see control type sensors (I know from painful experience).
I hope this helps.
References:
SuperIO
Mainboard
Looks like you need the following to turn on the fan reader:
computer.FanControllerEnabled = true;
You're only looking for sensors nested inside the CPU object.
There actually are temperature sensors inside the CPU, but the fans are neither inside the CPU nor connected to it. Your "CPU fan" is called that because it's physically placed atop the CPU to cool it.
Look for Fan sensors elsewhere in the tree. On my system they're displayed within the motherboard object. You'll find additional measurements of CPU temperature there as well, from sensors placed on the outside of the CPU module. The CPU voltage as well is sensed outside the CPU, at least on my system, and therefore nested within the motherboard and not the CPU in the hardware monitoring tree.
As bland noted, the myComputer.CPUEnabled = true; may not be sufficient to enable the rest of the sensor tree.

What is the ideal approach to get the duplicate phone numbers in iphone - MonoTouch

I'm trying to get the duplicate phone numbers on iPhone address book . my problem that it's really taking time i have like 264 contact on my iPhone and the process taking like 16 sec !!! i have purchased app from iTunes doing same process taking like no time .
so i believe that my approach is incorrect . i know that in Xcode i should use NSPredicate . i tried to do that with c# predicate but same result . below is my code to get duplicate phone numbers :
ABAddressBook ab = new ABAddressBook ();
OrderedDictionary persons = new OrderedDictionary ();
foreach (ABPerson p in ab.GetPeople()) {
foreach (var phoneNumber in p.GetPhones().GetValues()) {
var duplicates = SearchByPhoneNumber (ab, phoneNumber);
if (duplicates.Count > 1) {
if (!persons.Contains (phoneNumber)) {
persons.Add (phoneNumber, duplicates);
}
}
}
}
private List<ABPerson> SearchByPhoneNumber ( ABAddressBook ab, string phoneNumber)
{
List<ABPerson> duplicatepeople = new List<ABPerson> ();
phoneNumber = Regex.Replace (phoneNumber, "[^0-9]", "");
var people = ab.Where(x=> x is ABPerson).Cast<ABPerson>()
.Where((e)=> { return (e.GetPhones().Any((p)=>{return (Regex.Replace(p.Value,"[^0-9]", "")==phoneNumber); }));}).ToList ();
return people;
}
This runs in about 150 ms on my iPhone 4s.
NSError err;
ABAddressBook ab = ABAddressBook.Create(out err);
Dictionary<string,List<string>> phones = new Dictionary<string,List<string>> ();
ab.RequestAccess(delegate(bool granted,
NSError error) {
if (granted)
{
foreach (ABPerson p in ab.GetPeople()) {
foreach (var phoneNumber in p.GetPhones().GetValues()) {
if (phones.ContainsKey(phoneNumber))
{
phones[phoneNumber].Add (p.FirstName + " " + p.LastName);
}
else
{
phones.Add (phoneNumber,new List<string>() { p.FirstName + " " + p.LastName });
}
}
}
var dupes = (from x in phones where x.Value.Count() > 1 select x);
foreach(var d in dupes)
{
Console.Write(d.Key + ": ");
foreach (string s in d.Value)
{
Console.Write(s + ", ");
}
Console.WriteLine();
}
}
});

Categories