在Form1顶部,我添加了这个:
bool completed;
AutoResetEvent autoreset;
在构造函数中我做了:
completed = false;
autoreset = new AutoResetEvent(false);
在我做过的背景工作者DoWork活动中:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
completed = 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));
//listBox1.DataSource = data;
}
}
autoreset.Set();
}
然后在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
{
if (completed == true)
{
this.backgroundWorker1.CancelAsync();
autoreset.WaitOne();
}
}
}
当它正在执行WaitOne()时,表单刚刚显示在中间并且程序冻结我可以做的就是在visual studio Debug&gt; Stop Debugging
我想这样做是为了aovid例外我有时会得到一些关于多线程的RaceOnRCWCleanup。
有时当关闭程序时,我遇到了另一个类这个例外:
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:
就像在backgroundworker完成作业之前处理的form1一样,backgrounddworker dowork事件正在使用这个类方法。
答案 0 :(得分:2)
假设Bgw首先是你的背景工作者,你将设置:
Bgw.WorkerSupportsCancellation = true;
然后在你的DoWork委托中你必须检查Bgw.CancellationPending是真还是假。
如果确实这意味着背景工作者已被取消,那么如果不能继续,则必须中止该功能。
答案 1 :(得分:0)
试试这个:
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (!backgroundWorker1.CancellationPending)
{
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.BeginInvoke(new Action(() => data = new List<string>()));
tempCpuValue = Core.cpuView(pauseContinueDoWork, cpu, this, data, tempCpuValue, button1);
tempGpuValue = Core.gpuView(pauseContinueDoWork, data, tempGpuValue, button1);
this.BeginInvoke(new Action(() => listBox1.DataSource = null));
this.BeginInvoke(new Action(() => listBox1.DataSource = data));
}
completed = true;
autoreset.Set();
}
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
{
if (!completed)
{
this.backgroundWorker1.CancelAsync();
Hide(); // hide the form while waiting for the bw to terminate
autoreset.WaitOne();
}
}
}
我已将来自Invoke
的来电更改为BeginInvoke
,这可以缓解您的问题。