我刚开始学习c#中的线程和方法,但我遇到了一个我找不到解决方案的问题。
我制作了一个基本的C#表单程序,通过启动一个线程并调用委托来不断更新和显示一个数字。
在Form1_load上启动新线程:
private void Form1_Load(object sender, EventArgs e)
{
t = new System.Threading.Thread(DoThisAllTheTime);
t.Start();
}
Public void DoThisAllTheTime(不断更新数字):
public void DoThisAllTheTime()
{
while(true)
{
if (!this.IsDisposed)
{
number += 1;
MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
this.Invoke(yolo);
}
}
}
现在,当我单击表单的X按钮时,出现以下异常:
'System.Windows.Forms.dll中发生了'System.ObjectDisposedException'类型的未处理异常
无法更新已删除的对象'
虽然我确实检查了表格是否已被处理。
编辑:我在修复问题的代码中添加了catch(ObjectDisposedException ex)。 工作代码: public void DoThisAllTheTime()
{
while(true)
{
number += 1;
try {
MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
this.Invoke(yolo);
}
catch (ObjectDisposedException ex)
{
t.Abort();
}
}
}
答案 0 :(得分:3)
您对this.IsDisposed
的来电总是过时的。您需要拦截表单结束事件并明确停止该线程。那么你根本不需要进行IsDisposed
测试。
有很多方法可以做到这一点。就个人而言,我会使用System.Threading.Tasks
命名空间,但是如果你想继续使用System.Threading
,你应该定义一个成员变量_updateThread
,并在你的load事件中启动它:
_updateThread = new System.Threading.Thread(DoThisAllTheTime);
_updateThread.Start();
然后在你的结束活动中:
private void Form1_Closing(object sender, CancelEventArgs e)
{
_stopCounting = true;
_updateThread.Join();
}
最后,替换IsDisposed
测试并检查新_stopCounting
成员变量的值:
public void DoThisAllTheTime()
{
MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
while(!_stopCounting)
{
number += 1;
this.Invoke(yolo);
}
}
答案 1 :(得分:2)
只需将此覆盖放在表单类中:
protected override void OnClosing(CancelEventArgs e) {
t.Abort();
base.OnClosing(e);
}
答案 2 :(得分:-3)
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Thread.CurrentThread.Abort();
}