2011-05-25 39 views
3

我有一個c#3.5框架Windows應用程序,它運行在位於服務器上的Oracle數據庫中。完成隊列不能快速釋放

其中一個應用程序的形式有在頂部八個選項卡。每個選項卡的選項卡內容區域內都有一個組合框。組合框在每個表單上顯示相同的信息。當用戶使用下拉或鍵盤箭頭更改組合框值時,八個選項卡區域將填充從Oracle提取的數據。

基於現有的程序的結構,每次組合框改變時,約20個單獨的DB連接被打開。首先,調用約8個來將不同標籤中的數據保存到正確的表格中。每個選項卡的內容都被傳遞給一個DB類以保存該選項卡的數據。其次,大約8個DB調用是基於組合框從表格中加載標籤。

爲了澄清,它會像改變汽車的模型中的任何選項卡上選擇一個組合框。然後每個選項卡將像「內部選項」,「引擎選項」等東西。

然後幾個數據庫調用被鎖定基於一個ID的高級記錄,所以沒有其他人可以編輯該特定的記錄與此同時。

整個過程非常穩固。保存/加載時間非常快。我可以在兩個不同的組合框之間來回切換,幾乎可以實現即時的數據保存/加載。

那麼問題來了

如果我旋來回足夠快(一對夫婦的用戶都要做的事),整個程序掛起。沒有崩潰,只是掛起。

在調試ENVIRON重複此,我發現它總是在同一行的代碼停止(一個簡單的記錄集分配(例如CarModelInterior.Notes = Convert.ToString(myReader [6]);)

然後我發現垃圾收集器(GC)線程在後臺運行,但每次也停在同一個地方。

輸入安裝紅門內存/性能監視器。

我發現是我越來越快地切換c Oombobox值,GC Finalizer隊列填滿的速度就越快。最終,似乎相同的SQL調用位於列表的頂部。

進入我的假設和猜測。

我的想法是,要麼有打開的連接太多而沒有被最終確定速度不夠快或者是有鎖的地方去上。

我能說的是,在整個節目我的數據庫調用所有(每嚇壞之一)使用「使用」的聲明,因此所有產權處置是自動完成。此外,所有(如在我檢查整個應用程序),所有的數據庫調用都在主線程上。因此,爲每個組合框值所做的20個左右的DB調用都是按順序進行的。這至少在可能的單線程問題上消除了鎖定的可能性。

我還剩下什麼?在這一點上,這麼多的搜索引擎,我已經放棄並張貼在這裏。是否有可能finalize隊列處理速度不夠快?任何其他想法?

+3

問題是爲什麼(以及用什麼對象?)最終確定隊列填滿了第一位?如果你正在處理你的資源,Dispose調用應該執行'GC.SuppressFinalize()'來避免這個問題。 – BrokenGlass 2011-05-25 18:09:13

+0

碎玻璃做了精明的觀察。另外,是否有任何鎖定原語可能在共享資源上死鎖?也許,它在數據訪問層(你沒有提及;它是什麼?) – sehe 2011-05-25 18:13:19

+0

在Red Gate程序中列出的所有值都被「未放置的對象」過濾,並且都是OracleCommand對象。掛起時列表頂部的一個(有幾個內存快照以確認它不是清除隊列)是一個刪除SQL。 因爲我可以重現錯誤,它是單線程的,它怎麼會是一個鎖定錯誤? (無辜的問題) – joe 2011-05-25 18:24:59

回答

1

必須先處理OracleCommand才能回收資源。通常Command對象的基類爲DbCommand,它實現了IDisposable。相比之下,System.Data.SqlClient.SqlCommand似乎不需要配置,因此它可能會導致開發人員忘記許多DbCommand實現需要處理。 如果不處理這些命令,那麼垃圾收集器將通過調用Finalize方法(假定您的Oracle客戶端的OracleCommand實現覆蓋object.Finalize)來最終釋放非託管資源。