简体   繁体   English

为什么我总是得到InvalidOperationException?

[英]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. 当游戏运行时,我看到使用断点,pname赢得了一个游戏过程的索引。 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. 然后我在类中有一个方法我用Form1中的一个计时器调用它,它将日志文件写入GPU视频卡的温度。 This part was working good untill i added this pname process. 这部分工作得很好,直到我添加了这个pname进程。

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 ! 我希望如果温度例如是123c,那么立刻杀死/关闭/关闭游戏! 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: 第172行是:

//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. Process.Kill()的文档显示,如果进程未运行,它可能引发InvalidOperationException。

Maybe try: pname.Where(p => !p.HasExited).ToList().ForEach(p => p.Kill()); 也许试试: 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. 问题是您的pname列表中的一个或多个实例不在您期望的状态。 As pointed out in another answer this could be because the process isn't running. 正如另一个答案所指出的,这可能是因为该过程没有运行。 Also, one of the references could be null . 此外,其中一个引用可能为null To prevent the exception try adding a where clause like the following; 要防止异常,请尝试添加如下的where子句;

 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. 我不熟悉的Process类,所以我不完全相信你会想用在那第二个条件是什么Where ,但应该给你的想法。 This will just filter out instances in the list that would cause the error before calling Kill() . 这只会在调用Kill()之前过滤出导致错误的列表中的实例。

The only problem i can see in your code is you are not clearing the pname object. 我可以在你的代码中看到的唯一问题是你没有清除pname对象。 If the pname has reference to a process that is no longer running, you will get this exception. 如果pname引用了不再运行的进程,则会出现此异常。 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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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