【问题标题】:ObjectDisposedException after closing application on Timer在 Timer 上关闭应用程序后的 ObjectDisposedException
【发布时间】:2014-10-02 03:21:43
【问题描述】:

我正在开发一个网络应用程序。首先,我想让 DataGridView 每秒刷新一次数据。我的实现:

public partial class Form1 : Form
{
    BindingList<Wifi> Networks = new BindingList<Wifi>();
    System.Timers.Timer NetworksRefreshThread;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        NetshScanner netshScanner = new NetshScanner();
        NetworksRefreshThread = new System.Timers.Timer(1000);

        dataGridView1.DataSource = Networks;
        NetworksRefreshThread.Elapsed += delegate
        {         
            BindingList<Wifi> tmp = new BindingList<Wifi>(netshScanner.StartAndParseOutput());

                this.Invoke((MethodInvoker)delegate
                {
                    Networks.Clear();
                    foreach (Wifi net in tmp)
                    {
                        Networks.Add(net);
                    }

                });

        };
    }

关闭表单后,我在 this.Invoke 中得到 ObjectDisposedException。有什么建议吗?

【问题讨论】:

  • 关闭表单时是否停止运行计时器?
  • 我在 Form1_FormClosing 事件中添加了 NetworksRefreshThread.Close() 但仍然相同。我要补充一点,这个异常并不总是出现。

标签: c# multithreading exception timer task


【解决方案1】:

可能发生的情况是计时器已触发并且当前正忙于刷新您的 DataGridView。这发生在单独的线程上。 然后,当您关闭表单时,GUI 线程开始销毁其对象。 之后,计时器完成检索其新数据,但没有对象可以放置。

解决这个问题。在您的类中添加一个名为“更新”或类似名称的布尔值。然后在更新为 true 时设置它的值。

NetworksRefreshThread.Elapsed += delegate
{    
    Updating = true;     
    BindingList<Wifi> tmp = new BindingList<Wifi>(netshScanner.StartAndParseOutput());

        this.Invoke((MethodInvoker)delegate
        {
            Networks.Clear();
            foreach (Wifi net in tmp)
            {
                Networks.Add(net);
            }

        });
    Updating = false;
};

现在创建一个绑定到 Form 关闭事件的新方法。在此方法中,在计时器更新时执行 Thread.Sleep():

while (Updating) Thread.Sleep(100);

【讨论】:

  • 但是更新是在 GUI 线程中完成的,这就是我使用this.Invoke((MethodInvoker)delegate) 的原因。在计时器内部,我获取tmp 变量的数据并将其提供给GUI 线程进行更新。
  • 好吧,你试着让 GUI 线程来做……但是在你关闭表单后 GUI 线程就不再存在了。
  • 这似乎是问题所在,但是当我使用 Update 布尔值修改代码时,应用程序会在出现这种情况时冻结。
猜你喜欢
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多