ObjectDisposedException was caught.
Cannot access a disposed object.
Object name: ‘Form1’.
Thats when the backgorundworker is working and i click the X red X on the right top corner to close the application when its in the middle of the work sometimes its throwing this exception.
System.ObjectDisposedException was caught
Message=Cannot access a disposed object.
Object name: 'Form1'.
Source=System.Windows.Forms
ObjectName=Form1
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.Invoke(Delegate method)
at GatherLinks.Form1.test(String url, Int32 levels, DoWorkEventArgs eve) in D:\C-Sharp\GatherLinks\GatherLinks\GatherLinks\Form1.cs:line 126
InnerException:
Line 126 in this case is:
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, " Done " + Environment.NewLine, Color.Red); }));
What should i do to fix/repair this exception and what objects or variables should i release/close when exiting the application ?
The test function:
private List<string> test(string url, int levels,DoWorkEventArgs eve)
{
levels = levelsToCrawl;
HtmlWeb hw = new HtmlWeb();
List<string> webSites;
List<string> csFiles = new List<string>();
csFiles.Add("temp string to know that something is happening in level = " + levels.ToString());
csFiles.Add("current site name in this level is : " + url);
try
{
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, "Loading The Url: " + url + "..." , Color.Red); }));
HtmlAgilityPack.HtmlDocument doc = GetHtmlDoc(url, reqOptions, null);
if (timeOut == true)
{
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, " There Was A TimeOut" + Environment.NewLine , Color.Red); }));
timeOut = false;
return csFiles;
}
else
{
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, " Done " + Environment.NewLine, Color.Red); }));
}
currentCrawlingSite.Add(url);
webSites = getLinks(doc);
removeDupes(webSites);
removeDuplicates(webSites, currentCrawlingSite);
removeDuplicates(webSites, sitesToCrawl);
if (removeExt == true)
{
removeExternals(webSites);
}
if (downLoadImages == true)
{
retrieveImages(url); }
if (levels > 0)
sitesToCrawl.AddRange(webSites
this.Invoke(new MethodInvoker(delegate { label7.Text = sitesToCrawl.Count.ToString(); }));
this.Invoke(new MethodInvoker(delegate { label3.Text = currentCrawlingSite.Count().ToString(); }));
if (levels == 0)
{
return csFiles;
}
else
{
for (int i = 0; i < webSites.Count(); i++)//&& i < 20; i++) {
int mx = Math.Min(webSites.Count(), 20);
string t = webSites[i];
if ((t.StartsWith("http://") == true) || (t.StartsWith("https://") == true))
{
csFiles.AddRange(test(t, levels - 1, eve));
}
}
return csFiles;
}
}
catch
{
return csFiles;
}
}
And the backgroundworker DoWork and ProgressReport events:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.Invoke(new MethodInvoker(delegate { label2.Text = "Website To Crawl: "; }));
this.Invoke(new MethodInvoker(delegate { label4.Text = mainUrl; }));
test(mainUrl, levelsToCrawl, e);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
Looks like your form is being disposed, and then your BackgroundWorker is trying to update a control which belonged to the disposed form.
You could handle your form’s
FormClosingevent and stop the worker, or wait for it to complete.Alternatively, your BackgroundWorker could check the form’s
IsDisposedproperty before attempting to write out the status.But really, you should be using
ReportProgress, rather thanInvoke– which would avoid the problem as well.