2012-09-18 9 views
1

ObjectDisposedException이 (가) 검색되었습니다.작업을하는 동안 응용 프로그램을 닫을 때 때때로 객체를 공개하지 않는 예외가 발생합니다. 이유는 무엇입니까?

폐기 된 개체에 액세스 할 수 없습니다. 개체 이름 : 'Form1'.

그 때 backgorundworker가 작동하고 있으며 작업 중간에 응용 프로그램을 닫을 때 오른쪽 상단 모서리에있는 X 빨간색 X를 클릭하면이 예외가 throw되는 경우가 있습니다. 이 경우

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: 

라인 (126) 은 다음과 같습니다

this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, " Done " + Environment.NewLine, Color.Red); })); 

내가 뭘/수리이 예외를 해결하기 위해해야 ​​할 응용 프로그램을 종료 할 때 어떤 개체 또는 변수 내가/닫기 해제해야합니까?

테스트 기능 :

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; 
      } 

     } 

그리고 BackgroundWorker 구성 DoWork 및 ProgressReport 이벤트 : 양식에 배치되고처럼

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) 
     { 


     } 
+0

해당 코드의 원인에 대한 컨텍스트가 없으면 Form, 'Form1'이 삭제 된 다음 이벤트가 호출되기 때문에 거의 확실합니다. – pickypg

+0

가능한 [양식의 닫는 이벤트에 BackgroundWorker를 중지하는 방법?] (http://stackoverflow.com/questions/1731384/how-to-stop-backgroundworker-on-forms-closing-event) –

답변

2

은 같은데, 다음 BackgroundWorker에이 속한 컨트롤을 업데이트하기 위해 노력하고있다 폐기 된 형태로.

양식의 FormClosing 이벤트를 처리하고 작업자를 중지 시키거나 완료 될 때까지 기다릴 수 있습니다.

또는 BackgroundWorker는 상태를 기록하기 전에 양식의 IsDisposed 속성을 확인할 수 있습니다.

하지만 실제로는 Invoke이 아닌 ReportProgress을 사용해야합니다. 그러면 문제가 방지됩니다.

+0

어떻게해야합니까? 보고 진행 중이 니? 테스트 기능은 항상 스스로 작동하는 기능을합니다. 백그라운드 작업자 DoWork 이벤트에서이 테스트 함수를 처음 호출합니다. 그런 다음 기능 테스트는 항상 자체 호출합니다. backgroundworker ReportProgress 이벤트에서 지금 아무것도하지 않습니다. 그래서 어떻게 든 테스트 함수에서보고하고 reportprogress 이벤트에서 뭔가를해야합니다. 어떻게해야합니까? –

+0

방금 ​​전체 테스트 기능으로 내 질문을 업데이트했습니다. –

관련 문제