Complete program that give exception ObjectDisposed was unhandled by user

T

Tony Johansson

Hi!

Here I have a complete program that includes every file such as main and so
on.
When this program starts it displays a form called form2 with a single
button.
When this button is clicked a windows form is started with name
ProgBarAndTimer that use a timer to update a progressbar.
The timer can be started and stopped by using two buttons called start and
stop.

The program works perfectly except for when I close the ProgBarAndTimer
form.
The problem that I have then is when I close the ProgBarAndTimer form the
program cause an Exception.
The Exception error says an "ObjectDisposedException was unhandled by user
code". It says also translated to english "It's not possible to access a
removed object.Objectname:progBarAndTimer"

So to see this exception ObjectDisposedException was unhandled by user code
you just start the program and click the button
and then close the ProgBarAndTimer form which is the form with the
progressbar in..

What can I do to solve my problem with ObjectDisposedException was unhandled
by user code ?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form2());
}
}

public partial class Form2 : Form
{
private System.ComponentModel.IContainer components = null;
private System.Windows.Forms.Button button1;

public Form2()
{
InitializeComponent();
}

protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
components.Dispose();
base.Dispose(disposing);
}

private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
this.button1.Location = new System.Drawing.Point(85, 77);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 270);
this.Controls.Add(this.button1);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);
}

private void button1_Click(object sender, EventArgs e)
{
new ProgBarAndTimer().Show();
}
}

public partial class ProgBarAndTimer : Form
{
private delegate void MyInfoCallback(string msg);
private System.Timers.Timer myTimer = new System.Timers.Timer();
private int myValue = 1;

public ProgBarAndTimer()
{
InitializeComponent();
myTimer.Elapsed += new
System.Timers.ElapsedEventHandler(myTimer_Elapsed);
myTimer.Interval = 100;
numUpDown.Value = 100;
numUpDown.Maximum = 1000;
numUpDown.Minimum = 100;
prgValue.Value = 50;
myTimer.Enabled = true;
}

void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
UpdateValue(myValue.ToString());
}

private void UpdateValue(string msg)
{
if (this.InvokeRequired)
{
this.Invoke(new MyInfoCallback(UpdateValue), msg);
}
else
{
if (prgValue.Value == 100)
prgValue.Value = 0;

prgValue.Value += 1;
lblValue.Text = prgValue.Value.ToString();
}
}

private void btnStart_Click(object sender, EventArgs e)
{
myTimer.Enabled = true;
}

private void btnStop_Click(object sender, EventArgs e)
{
myTimer.Enabled = false;
}

private void numUpDown_ValueChanged(object sender, EventArgs e)
{
numUpDown.Increment = 100;
myTimer.Interval = Convert.ToDouble(numUpDown.Value);
}
}


partial class ProgBarAndTimer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnStart = new System.Windows.Forms.Button();
this.btnStop = new System.Windows.Forms.Button();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.numUpDown = new System.Windows.Forms.NumericUpDown();
this.label2 = new System.Windows.Forms.Label();
this.prgValue = new System.Windows.Forms.ProgressBar();
this.label3 = new System.Windows.Forms.Label();
this.lblValue = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numUpDown)).BeginInit();
this.SuspendLayout();
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(21, 12);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(75, 23);
this.btnStart.TabIndex = 0;
this.btnStart.Text = "Start";
this.btnStart.UseVisualStyleBackColor = true;
this.btnStart.Click += new
System.EventHandler(this.btnStart_Click);
//
// btnStop
//
this.btnStop.Location = new System.Drawing.Point(21, 44);
this.btnStop.Name = "btnStop";
this.btnStop.Size = new System.Drawing.Size(75, 23);
this.btnStop.TabIndex = 1;
this.btnStop.Text = "Stop";
this.btnStop.UseVisualStyleBackColor = true;
this.btnStop.Click += new System.EventHandler(this.btnStop_Click);
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(161, 12);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(118, 21);
this.comboBox1.TabIndex = 2;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(122, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(33, 13);
this.label1.TabIndex = 4;
this.label1.Text = "Style:";
//
// numUpDown
//
this.numUpDown.Location = new System.Drawing.Point(212, 42);
this.numUpDown.Name = "numUpDown";
this.numUpDown.Size = new System.Drawing.Size(118, 20);
this.numUpDown.TabIndex = 5;
this.numUpDown.ValueChanged += new
System.EventHandler(this.numUpDown_ValueChanged);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(122, 44);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(88, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Speed(ms delay):";
//
// prgValue
//
this.prgValue.Location = new System.Drawing.Point(21, 88);
this.prgValue.Name = "prgValue";
this.prgValue.Size = new System.Drawing.Size(505, 23);
this.prgValue.TabIndex = 7;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(18, 114);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(37, 13);
this.label3.TabIndex = 8;
this.label3.Text = "Value:";
//
// lblValue
//
this.lblValue.AutoSize = true;
this.lblValue.Location = new System.Drawing.Point(61, 114);
this.lblValue.Name = "lblValue";
this.lblValue.Size = new System.Drawing.Size(0, 13);
this.lblValue.TabIndex = 9;
//
// ProgBarAndTimer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(552, 214);
this.Controls.Add(this.lblValue);
this.Controls.Add(this.label3);
this.Controls.Add(this.prgValue);
this.Controls.Add(this.label2);
this.Controls.Add(this.numUpDown);
this.Controls.Add(this.label1);
this.Controls.Add(this.comboBox1);
this.Controls.Add(this.btnStop);
this.Controls.Add(this.btnStart);
this.Name = "ProgBarAndTimer";
this.Text = "Progressbar and Timer";
((System.ComponentModel.ISupportInitialize)(this.numUpDown)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.Button btnStop;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.NumericUpDown numUpDown;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.ProgressBar prgValue;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label lblValue;
}

//Tony
 
P

Peter Duniho

Tony said:
Hi!

Here I have a complete program that includes every file such as main and so
on.
When this program starts it displays a form called form2 with a single
button.
When this button is clicked a windows form is started with name
ProgBarAndTimer that use a timer to update a progressbar.
The timer can be started and stopped by using two buttons called start and
stop.

The program works perfectly except for when I close the ProgBarAndTimer
form.
The problem that I have then is when I close the ProgBarAndTimer form the
program cause an Exception. [...]

You have a variety of multi-threading bugs in your code, but the one
that is causing the problem is that your timer thread is trying to use
the form you closed, which is disposed when it's closed.

As it happens, I wrote a couple of articles on the topic awhile ago.
The basic idea is to make sure you have a way of knowing whether the
form's been closed or not, and avoiding trying to use it when it has
been. Here are the links:
http://msmvps.com/blogs/duniho/archive/2008/09/12/form-closing-race-condition.aspx
http://msmvps.com/blogs/duniho/archive/2008/09/12/form-closing-race-condition-part-2.aspx

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top