关闭窗体时的异常(thread + invoke) [英] Exception when closing Form (thread + invoke)

查看:559
本文介绍了关闭窗体时的异常(thread + invoke)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习c#中的线程和方法,但是遇到一个问题,我找不到解决方案。



我做了一个基本的C#表单程序,通过启动一个线程并调用委托来保持更新和显示一个数字。



在Form1_load上启动新线程:

  private void Form1_Load(object sender,EventArgs e)
{
t = new System.Threading.Thread(DoThisAllTheTime);
t.Start();
}

公共无效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();
}
}
}


解决方案

您致电 this.IsDisposed 始终过期。你需要拦截你的表单关闭事件并明确地停止线程。那么你根本就不必这样做 IsDisposed 测试。



有很多方法可以做到这一点。个人来说,我将使用 System.Threading.Tasks 命名空间,但如果您想保留使用 System.Threading ,你应该定义一个成员变量 _updateThread ,并在你的加载事件中启动它:

 code> _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);
}
}


I have just started to learn about threads and methodinvoking in c#, but I have come across a problem which I couldn't find the solution of.

I made a basic C# form program which keeps updating and displaying a number, by starting a thread and invoke delegate.

Starting new thread on Form1_load:

private void Form1_Load(object sender, EventArgs e)
  {
        t = new System.Threading.Thread(DoThisAllTheTime);
        t.Start();
  }

Public void DoThisAllTheTime (which keeps updating the number) :

public void DoThisAllTheTime()
  {
     while(true)
      {
        if (!this.IsDisposed)
         {
           number += 1;
           MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
           this.Invoke(yolo);
         }
      }
  }

Now when I click the X button of the form, I get the following exception:

'An unhandled exception of type 'System.ObjectDisposedException' occurred in System.Windows.Forms.dll

Can't update a deleted object'

While I actually did check if the form was disposed or not.

EDIT: I added catch (ObjectDisposedException ex) to the code which fixed the problem. Working code:

  public void DoThisAllTheTime()
  {
     while(true)
      {
         number += 1;

         try {  
              MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
              this.Invoke(yolo);
             }
         catch (ObjectDisposedException ex)
             {
              t.Abort();
             }
      }
 }

解决方案

Your call to this.IsDisposed is always out of date. You need to intercept your form closing event and stop the thread explicitly. Then you won't have to do that IsDisposed test at all.

There are many ways you can do this. Personally, I would use the System.Threading.Tasks namespace, but if you want to keep your use of System.Threading, you should define a member variable _updateThread, and launch it in your load event:

_updateThread = new System.Threading.Thread(DoThisAllTheTime);
_updateThread.Start();

Then in your closing event:

private void Form1_Closing(object sender, CancelEventArgs e)
{
    _stopCounting = true;
    _updateThread.Join();
}

Finally, replace the IsDisposed test with a check on the value of your new _stopCounting member variable:

public void DoThisAllTheTime()
{
    MethodInvoker yolo = delegate() { label1.Text = number.ToString(); };
    while(!_stopCounting)
    {
        number += 1;
        this.Invoke(yolo);
    }
}

这篇关于关闭窗体时的异常(thread + invoke)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆