简体   繁体   中英

Why im getting all the time InvalidOperationException?

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM