工做中遇到的一個多線程下致使RCW沒法釋放的問題

最近有個同事在調用一個類庫中的方法時遇到了一個問題,異常信息以下:多線程

嘗試釋放正在使用的RCW,活動線程或其餘線程上正在使用該 RCW,釋放正在使用的 RCW 的嘗試會致使損壞或數據丟失。測試

該方法中對word文件進行相關了操做,由於我以前也在多線程環境下調用過該方法,而且沒遇到這個問題,因此同事讓我過去看看怎麼回事。這個方法在對文件進行相關操做後,會調用另一個方法釋放word對象,部分代碼以下:ui

Word._Application t = oWord as Word._Application;
object oIsSave = false;
t.Quit(ref oIsSave, ref oMissing, ref oMissing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDoc);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWord);
oWord = null;
oDoc = null;
GC.Collect();
GC.Collect();

該段代碼是爲了保證當即釋放word對象並關閉word進程。由於異常信息定位在這裏,因此我過去後就從這裏開始看,可是看了半天,也沒看出類庫中的方法有什麼問題,由於以前我使用的時候沒遇到這種狀況,所以我以爲可能不會是這裏的問題,而且我負責的那個產品已經通過了大量的測試,確定是沒問題的,因此我說讓我看看你是怎麼調用的吧,打開他的代碼看了一眼,總體上沒什麼其餘問題,可是有個地方引發了個人注意,代碼中對該類的實例化放在了全局範圍,由於是個cs項目,這麼作會致使該對象始終被引用,所以即便在垃圾回收時也沒法被釋放,而這裏調用的又是com組件,就致使了word進程沒法關閉,而且同事在這裏用的是多線程,因此程序一運行起來,會出現一大堆word進程關不掉。因而就將這裏的對象實例化放到了線程方法中,這樣在方法執行結束後,堆中的對象就處於無引用狀態,在垃圾回收時就被釋放了,問題就天然解決了。其實這裏跟單線程仍是多線程不要緊,主要是在全局範圍內進行實例化致使了對象不能被垃圾回收,因此在寫代碼的時候必定要注意對象的生命週期。線程

相關文章
相關標籤/搜索