在Form1中我有这段代码:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are you Sure you want to Exit. Click Yes to Confirm and No to continue", "WinForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
e.Cancel = true;
}
else
{
this.backgroundWorker1.CancelAsync();
}
}
然后我做了一个新课程:
class Core
{
public static Form1 form1;
public Core(Form1 f)
{
form1 = f;
}
public static float? cpuView(bool pause , CpuTemperature cpuTemp , Form1 f1 , List<string> myData , float? myCpuTemp , Button b1)
{
if (pause == true)
{
}
else
{
Computer myComputer = new Computer();
myComputer = new Computer(cpuTemp)
{
CPUEnabled =
true
};
myComputer.Open();
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.Temperature)
{
sensor.Hardware.Update();
cpuTemp.GetValue("sensor", sensor.Value.ToString());
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
myCpuTemp = sensor.Value;
if (sensor.Value > 60)
{
Logger.Write("The Current CPU Temperature Is ===> " + sensor.Value);
b1.Enabled = true;
}
break;
}
}
}
}
}
return myCpuTemp;
}
例外是在线:
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
我认为产生问题的处理对象是Form1它自己。
System.ObjectDisposedException was unhandled by user code
HResult=-2146232798
Message=Cannot access a disposed object.
Object name: 'Form1'.
Source=System.Windows.Forms
ObjectName=Form1
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.Invoke(Delegate method)
at HardwareMonitoring.Core.cpuView(Boolean pause, CpuTemperature cpuTemp, Form1 f1, List`1 myData, Nullable`1 myCpuTemp, Button b1) in d:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Core.cs:line 55
at HardwareMonitoring.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in d:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Form1.cs:line 427
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
InnerException:
然后处置什么?因为我没有在我的代码中做任何事情来处理()它。
也许问题是Form1,因为我在Form1中使用了backgroundworker而后台工作者正在使用这个类,如果我正在关闭程序,那么form1会被处理但是变量f1可能还在尝试做某事吗?
我该如何解决?
编辑**
更改了cpuView函数:
public static float? cpuView(bool pause , CpuTemperature cpuTemp , Form1 f1 , List<string> myData , float? myCpuTemp , Button b1)
{
try
{
if (pause == true)
{
}
else
{
Computer myComputer = new Computer();
myComputer = new Computer(cpuTemp)
{
CPUEnabled =
true
};
myComputer.Open();
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.Temperature)
{
sensor.Hardware.Update();
cpuTemp.GetValue("sensor", sensor.Value.ToString());
if (!f1.IsDisposed)
{
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
}
myCpuTemp = sensor.Value;
if (sensor.Value > 60)
{
Logger.Write("The Current CPU Temperature Is ===> " + sensor.Value);
b1.Enabled = true;
}
break;
}
}
}
}
}
}
catch(Exception err)
{
return null;
}
return myCpuTemp;
}
在调用行之前添加了一个检查,并添加了try和catch。 这可以吗 ?或者我应该为cpuView和gpuView做另一种方式?
编辑**
这是Form1中的backgroundworker dowork事件:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
if (tempCpuValue >= (float?)nud1.Value || tempGpuValue >= (float?)nud1.Value)
{
soundPlay = true;
NudgeMe();
}
else
{
soundPlay = false;
stop_alarm = true;
}
tempCpuValue = Core.cpuView(pauseContinueDoWork,cpu,this,data,tempCpuValue,button1);
tempGpuValue = Core.gpuView(pauseContinueDoWork,data,tempGpuValue,button1);
this.Invoke(new Action(() => data = new List<string>()));
tempCpuValue = Core.cpuView(pauseContinueDoWork, cpu, this, data, tempCpuValue, button1);
tempGpuValue = Core.gpuView(pauseContinueDoWork, data, tempGpuValue, button1);
this.Invoke(new Action(() => listBox1.DataSource = null));
this.Invoke(new Action(() => listBox1.DataSource = data));
}
}
}
答案 0 :(得分:1)
在调用之前检查表单是否已被处理。
if (!f1.IsDisposed)
{
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
}
此外,在你的一些for循环中,你应该添加一个取消检查,这样后台工作者就能更快完成。
if (CancellationPending) return;
即便如此,你仍然有可能得到处理后的例外情况。如果表单在IsDisposed
检查后和Invoke
调用之前关闭,那么您将获得异常。对于这种罕见的情况,添加错误处理并忽略它(这是一个在应用程序关闭时可以安全忽略的异常)。