none
如何解決 無法存取已處置的物件?? RRS feed

  • 問題

  •             Form[] frm = new Form[2];
                frm[0] = new Form1();
                frm[1] = new Form2();
                int iCount = 0;
                int Cycle = 1;
                bool isEnd = false;
    
                while (isEnd == false)
                {
                    iCount++;
                    for (int i = 0; i < frm.Length; i++)
                    {
                        Application.Run(frm[i]);
                        //frm[i].ShowDialog();
                    }
                    if (iCount > Cycle)
                    {
                        break;
                    }
                }

    Dear All~

        以上是我的程式碼,但每次第二次 while 的 application.run(frm[0])就會出現 ObjectDisposedException的錯誤訊息,請問這是為什麼??

        frm[0] !=null 所以再呼叫,應該沒問題壓,但是會出現 無法存取已處置的物件

        但是我將frm[0]=new form1()寫在while就可以了,所以表示application.run 之後 frm[0] 就會被解構了嗎???


    IDS

    2012年11月29日 上午 03:09

解答

  • 理論上 Application.Run() 只能有一次。

    Application.Run(frm[i]) 是指應用程式的訊息迴圈會以 frm[i] 為主,如果 frm[i] 結束了,整個應用程式的訊息迴圈會結束,當然 frm[i] 會被解構。

    如果你要自己控制 Application 的生命週期,那就不要基於 frm[i],而是只用 Application.Run(),但這樣的話應用程式結束時,你要自己呼叫 Application.Exit(),否則執行檔不會結束。

    以下為 MSDN 的說明:

    在 Win32 架構或 Windows Forms 應用程式中,訊息迴圈是程式碼中的常式,它會處理使用者事件,例如滑鼠點選和鍵盤按鍵。每個執行 Windows 架構的應用程式都需要有作用中的訊息迴圈,稱為主要訊息迴圈。當主要訊息迴圈關閉時,應用程式就會結束。在 Windows Forms 中,這個迴圈會在呼叫 Exit 方法關閉,或在執行主要訊息迴圈的執行緒上呼叫 ExitThread 方法時關閉。

    大部分的 Windows Forms 開發人員都需要使用這個版本的方法。您應該使用 Run(Form) 多載來啟動含有主要表單的應用程式,這樣應用程式就會在主要表單關閉時結束。在其他所有情況下,請使用 Run(ApplicationContext) 多載,這個多載支援提供 ApplicationContext 物件,能夠更妥善地控制應用程式的存留期。


    學習不是查個 Google 套個書上的範例就算了,而是去熟悉了解每個程式碼背後的意義,否則就算學個幾百年,它也不會是你的。

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2012年11月29日 上午 03:23
    版主

所有回覆

  • 理論上 Application.Run() 只能有一次。

    Application.Run(frm[i]) 是指應用程式的訊息迴圈會以 frm[i] 為主,如果 frm[i] 結束了,整個應用程式的訊息迴圈會結束,當然 frm[i] 會被解構。

    如果你要自己控制 Application 的生命週期,那就不要基於 frm[i],而是只用 Application.Run(),但這樣的話應用程式結束時,你要自己呼叫 Application.Exit(),否則執行檔不會結束。

    以下為 MSDN 的說明:

    在 Win32 架構或 Windows Forms 應用程式中,訊息迴圈是程式碼中的常式,它會處理使用者事件,例如滑鼠點選和鍵盤按鍵。每個執行 Windows 架構的應用程式都需要有作用中的訊息迴圈,稱為主要訊息迴圈。當主要訊息迴圈關閉時,應用程式就會結束。在 Windows Forms 中,這個迴圈會在呼叫 Exit 方法關閉,或在執行主要訊息迴圈的執行緒上呼叫 ExitThread 方法時關閉。

    大部分的 Windows Forms 開發人員都需要使用這個版本的方法。您應該使用 Run(Form) 多載來啟動含有主要表單的應用程式,這樣應用程式就會在主要表單關閉時結束。在其他所有情況下,請使用 Run(ApplicationContext) 多載,這個多載支援提供 ApplicationContext 物件,能夠更妥善地控制應用程式的存留期。


    學習不是查個 Google 套個書上的範例就算了,而是去熟悉了解每個程式碼背後的意義,否則就算學個幾百年,它也不會是你的。

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2012年11月29日 上午 03:23
    版主
  • Dear 小朱~~感謝您的回答,再跟您請教觀念問題!!

    我將frm[0]=new form1()寫在while就可以了

    所以表示application.run 之後 frm[0] 就會被解構了,然後我在application.run 之前在new 一次,才不會有問題!!

    但是當我debug的時候,我看frm[0]的狀態還不是null的,卻也無法application.run,為何會這樣???


    IDS

    2012年11月29日 上午 05:22
  • 物件被 Disposed 不代表它是 null,它只是被標記為己解構的物件而己。

    學習不是查個 Google 套個書上的範例就算了,而是去熟悉了解每個程式碼背後的意義,否則就算學個幾百年,它也不會是你的。

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2012年11月29日 上午 09:54
    版主