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 androidx.lifecycle.HasDefaultViewModelProviderFactoryAndroidViewIDE
- cannot access local variable where it is not associated with a value
- 【scala】問題cannot resolve symbol sparkSymbolSpark
- 併發問題的三大根源是什麼?
- 【根本原因分析】如何找到問題的根源?
- 遇到的cannot find module 'xxx' 問題
- virt-manager cannot open display問題
- [譯] 虛構問題,低質量軟體的根源
- 如何透過六西格瑪尋找問題根源?
- 學妹問我,併發問題的根源到底是什麼?
- Jquery DataTables解決 Cannot reinitialise DataTable 問題jQuery
- cannot read prpperty ‘start‘ of undefined(問題記錄)Undefined
- 跨域問題(CORS / Access-Control-Allow-Origin)跨域CORS
- Gitea CORS Access-Control-Allow-Origin 的問題GitCORS
- Access denied for user ‘root‘@‘localhost‘問題的解決localhost
- 關於React Native報Cannot access ‘serviceOf‘的解決方案React Native
- 執行npm update等命令出錯後如何分析問題根源NPM
- Servlet3:從根源瞭解並解決編碼問題Servlet
- TypeError: Descriptors cannot not be created directly問題的解決Error
- IDEA Cannot access alimaven (http://maven.aliyun.com/nexus/content/groups/public/)IdeaMavenHTTP
- 聯合國問題根源:並不是是科技發展惹的禍
- 關於/usr/bin/ld: cannot find -lXX的問題
- 一體成型電感粉末才是解決問題核心所在
- MySQL authentication plugin 'caching_sha2_password' cannot be loaded 問題MySqlPlugin
- 【問題處理】ORA-00376 file xx cannot be read at this time
- java併發程式設計 --併發問題的根源及主要解決方法Java程式設計
- 隱私洩露再受關注,問題根源在哪?平臺能做什麼?
- NodeJS+Express解決跨域問題:Access-Control-Allow-OriginNodeJSExpress跨域
- Apache解決Access-Control-Allow-Origin多域名跨域問題Apache跨域
- No 'Access-Control-Allow-Origin' header: 跨域問題踩坑記錄Header跨域
- (轉載)關於usr/bin/ld: cannot find -lxxx問題總結
- Error: DPI-1047: Cannot locate a 64-bit Oracle Client library: "問題ErrorOracleclient
- axios跨域問題 No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.iOS跨域Header
- IDEA在執行maven打war的時候報錯:Cannot access defaults field of PropertiesIdeaMaven
- k8s 環境下Cannot assign requested address問題解決K8S
- LightDB Canopy 常見報錯問題分析(二)DETAIL: Distributed relations cannot haveAI
- MySQL 8.0.13 密碼問題 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)MySql密碼Errorlocalhost
- vue 中引用echarts 初始化init undefind問題(Cannot read property ‘init‘ of undefined)VueEchartsUndefined
- 關於IPC和PTH使用者許可權問題,psexec拒絕訪問(Access Denied)的原因