关闭Timer上的应用程序后出现ObjectDisposedException

时间:2014-08-08 15:29:22

标签: c# multithreading exception timer task

我正在开发网络应用程序。首先,我想让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。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

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

解决这个问题。在您的类中添加一个名为&#39;更新&#39;的布尔值。或类似的东西。然后在更新为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);