Cannot access a disposed object.問題根源所在.....
轉自:http://xdeduzb.blog.163.com/blog/static/819936372010417557105/http://
帶有UI的C#程式在初始化介面或者由使用者觸發某一UI更新的時候常常會遇到這樣的JIT異常:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'XXXX'.
從字面上理解,就是無法得到一個已經被終止的物件。那麼在什麼情況下這樣的事情會發生呢?
看一段程式碼就能夠理解了。
Code
public AuthenticationForm()
{
// Required for Windows Form Designer support
InitializeComponent();
// TODO: Add any constructor code after InitializeComponent call
this.action = FormAction.View;
AppButtons.AppParent = this;
this.EDITCTLS = new Control[] {RoleDGrid, RegionDGrid, UserNameTBox, CheckAllButton, ClearAllButton, ActiveCkBox, RoleCheckAllButton, RoleClearAllButton};
this.Initialization();
BeginAuth("GetUser", new object[]{AddUserButton});
}
Main方法執行了MainForm的初始化,完成必要元件例項化和資料匯入,開始等待使用者輸入。
Ok,使用者這時候點選了一個登入選單,以上form constructor程式碼經事件觸發,開始執行,啪啪啪完成新form的初始化,最後一步看到BeginAuth方法,它要完成對使用者的驗證,如果驗證通過,登入Form要顯示,如果驗證失敗,主程式要返回錯誤資訊,終止此form的所有資源。
但請注意,這個BeginAuth可不能隨便寫寫。看看這段BeginAuth的實現吧:
DataManager.SendAsyncWSRequest(this, this.displayDelegate, spName, DataManager.XMLDOC.InnerXml, hash);
DataManager是資料底層傳輸處理的介面,它是通用的。DataManager要發出WebService的資料請求,然後獲得回答(response),再通過this傳入的CallingForm例項呼叫Form的另一個方法EndAuth。
callingForm.EndAuth(resultXML, spName, hash, new ResponseArgs(false, errorNode.InnerXml, AsyncFailType.WSCaught));
EndAuth要解析WebService的response,判斷是否驗證通過,和相應Form的資源如何響應。以下是簡單的EndAuth實現:
Code
if(resp.Success == false)
{
MessageBox.Show(re.Msg, spName + ": WebService call fails");
base.EndAuth(re.Msg, spName, hash, re);
this.Close();
return;
}
else
UpdateDisplay();
Form在失敗驗證之後會被馬上close掉,換句話說,this.Close()會終止form之前初始化的所有元件,GC不知不覺開始回收記憶體。。。。
本文的主題在這個return之後發生了。return一完成,它退到哪兒了?對,之前form constructor的BeginAuth之後,也就是說,form還沒有“出生”就已經被“墮”了。但被“墮”不等於什麼也沒有(null),畢竟“屍骨”猶在。MainForm在得知sub-form constructor返回以後就會執行類似顯示form的方法Show()。要秀就要拿到form控制程式碼,但老子(mainform)拿到的卻是一個夭折的孩子。。。當然怎麼show也於事無補了。悲慘的Cannot access a disposed object異常就這樣發生了。由於是從Mainform觸發,它會直接影響主程式,導致程式崩潰。
知道了來龍去脈,那麼怎樣避免呢?很簡單,
1. 不要在constroctor沒有做完之前就任意終止資源(原則性)
拿示例來說的話,就是不要將BeginAuth方法置於構造方法內,置於Form_load()方法中不失為一良策。
2. 在拿來show之前要判斷是否為空或已被終止(輔助性)
if (subForm!= null && !subForm.IsDisposed)
subForm.Show();
轉者注:我的問題在於開了一個執行緒在關閉視窗前沒有把它關掉,所以我在視窗關閉事件加入執行緒的Abort(),這個問題就解決了...
相關文章
- Cannot Access Pls Pages: 'mod_security: Access denied with code 400'
- 找到問題根源——評《Windows高階除錯》Windows高階除錯
- 【根本原因分析】如何找到問題的根源?
- [譯] 虛構問題,低質量軟體的根源
- 【scala】問題cannot resolve symbol sparkSymbolSpark
- 500 OOPS: cannot change directory問題OOP
- Cannot access androidx.lifecycle.HasDefaultViewModelProviderFactoryAndroidViewIDE
- O/S-Error: (OS 33) The process cannot access the fileError
- Jquery DataTables解決 Cannot reinitialise DataTable 問題jQuery
- 執行npm update等命令出錯後如何分析問題根源NPM
- Servlet3:從根源瞭解並解決編碼問題Servlet
- error C2248: cannot access protected member declared in class '****'Error
- 解決不能訪問 VMware Server Web Access 的問題ServerWeb
- Access denied for user ‘root‘@‘localhost‘問題的解決localhost
- TypeError: Descriptors cannot not be created directly問題的解決Error
- 解決mysql"Access denied fot user 'root'@'localhost'"問題MySqllocalhost
- cannot read prpperty ‘start‘ of undefined(問題記錄)Undefined
- Cannot connect on socket(25)_NetBackup 問題解決
- android studio Cannot reload AVD list問題Android
- 關於React Native報Cannot access ‘serviceOf‘的解決方案React Native
- 一體成型電感粉末才是解決問題核心所在
- java併發程式設計 --併發問題的根源及主要解決方法Java程式設計
- 隱私洩露再受關注,問題根源在哪?平臺能做什麼?
- access資料庫大資料量分頁的問題資料庫大資料
- 關於 informix 中檢視錶所在資料庫空間的問題ORM資料庫
- 跨域問題(CORS / Access-Control-Allow-Origin)跨域CORS
- Gitea CORS Access-Control-Allow-Origin 的問題GitCORS
- zeppelin spark SparkContext問題 Cannot call methods on a stopped SparkContextSparkContext
- (問題解決)Cannot set LC_CTYPE to default locale: No such file or directory
- “Operation is not valid due to the current state of the object.”Object
- 揭秘APP使用者大量流失根源:效能問題導致使用者體驗下降APP
- 從Access轉到MySql以後遇到的關於null問題MySqlNull
- MySQL authentication plugin 'caching_sha2_password' cannot be loaded 問題MySqlPlugin
- Java問題解決:The project cannot be built until build path errors are resolvedJavaProjectUIError
- 三星手機問題根源:忽視軟體服務不再重視創新
- ORA-07445 ACCESS_VIOLATION,UNABLE_TO_READ問題處理
- 11g RAC - single client access name (scan) 的設定問題client
- netbakcup備份時遇到 status 59: access to the client was not allowed 問題解決client