2011-02-27 49 views
2

我最近推出了一個新的ASP .Net應用程序。此應用程序使用.Net 4.0和實體框架4.它是一個「基本」CRUD應用程序。我幾乎完全使用EntityDataSource進行數據訪問。爲什麼我的新.Net 4.0 EF應用程序會隨機鎖定?

用戶已經報告了應用程序的「ocassional freeze」(它們都使用IE 8)。如果用戶關閉他的瀏覽器並重新開始,那麼應用程序就沒問題。它可能每天發生一次或兩次,通常是重度用戶。 (所以,我一直傾向於內存不足或某種其他類型的資源限制。)

直到就在前一段時間,我從未見過這種情況。它不會在客戶端PC和服務器上的事件日誌中留下任何內容。此外,IIS錯誤日誌或SQL日誌中沒有任何內容。

不久前,我終於發生了。我將所有的EntityDataSources切換爲每頁使用一個對象上下文。我下載了EF Profiler(這似乎是一個很棒的產品),並指出我在很多頁面上使用了多個對象上下文,這是因爲它們中的很多都有多個EntityDataSource。所以,我正在清理所有這一切,並測試每一頁,當你看到.... IE停止加載頁面!

起初,頁面開始加載緩慢(這是一個頁面,我已經修改爲使用單個對象上下文,所以儘管我仍然相信我需要在我的所有頁面中實現這種「單例」模式,但我猜猜它不是罪魁禍首!無論如何..),然後在某些時候我收到:

消息:Sys.WebForms.PageRequestManagerTimeoutException:服務器請求超時。

仍然沒有在事件日誌中。我也檢查了IIS網絡日誌,但沒有看到任何內容,但用肉眼很難閱讀,我可能不得不下載解析器以確保沒有任何內容。

無論如何,我決定啓動另一個窗口並導航到我的應用程序,並確定窗口工作正常,沒有問題。我回到停止響應的窗口,刷新它,等待...去我的應用程序的主頁(這基本上只是一些靜態html ..沒有..)。接下來,我在當前被凍結的窗口中打開了一個新選項卡,該選項卡正常工作。所以,我回到窗口,不能再從我的應用程序加載頁面,並嘗試一些其他網站.... espn.com加載罰款,msn.com加載罰款,然後我輸入我的應用程序主頁的URL(並嘗試在我的應用程序中的其他頁面),但沒有。 IIS甚至不會在其日誌文件中記錄嘗試(就像IE剛剛決定不再做「獲取」我的本地主機!)。最後,在等待一段時間(當我輸入這篇文章的時候),我現在在那個窗口中有這個錯誤信息:

Internet Explorer無法顯示網頁。你可以嘗試:這個問題可能是由各種問題引起的,包括:BLAH BLAH BLAH ...

所以,我跳回到那個窗口,它仍然可以瀏覽Internet站點。但是,當我嘗試訪問我的應用程序中的任何頁面時,我再次遇到任何問題(在標籤中旋轉藍色圓圈)。所以,我再次在同一瀏覽器中啓動一個新選項卡,並且可以很好地瀏覽我的應用程序。

我的應用程序對這個瀏覽器實例做了什麼,它將不再讓它加載它的任何頁面(事實上,它似乎甚至沒有在任何應用程序頁面上進行GET,因爲沒有任何東西新的IIS日誌...除了當我加載頁面在這些其他標籤和/或瀏覽器窗口工作正常,所以日誌記錄仍在工作......)?我將永遠感激可以幫助我解決這個問題的人。我不確定它會有什麼好處,但我會離開這個瀏覽器窗口,因爲有人可以告訴我一些事情來嘗試診斷這個問題。我覺得我很接近想出來。我終於有了一個窗戶,這是行爲不端。我害怕關閉窗口或在應用程序上做一個新的內部版本,直到我得到一些好的輸入來嘗試......

我應該補充一點,當這發生在我身上時,我在本地PC上運行,所以我是唯一的用戶,並只有一個窗口開放的應用程序..

雖然,我完全難倒!

回答

1

聽起來像一個請求只需要很長時間才能執行。除非使用http流水線(反正不支持),否則只允許Web瀏覽器保持兩個併發連接到單個Web服務器。不過,我的經驗是,這是每個瀏覽器,而不是每個標籤。

這就是爲什麼沒有在你的日誌顯示出來,因爲你的瀏覽器,因爲它在等待網頁加載完成,然後才能讀取另一頁從未發起的請求。我會開始研究在鎖定之前啓動的最後一個請求,它可能是由於某種原因鎖定並永不完成的頁面。

只要所有請求都是順序的,ASP.NET就只使用一個線程。只要同時觸發兩個請求,就會啓動一個新線程(調用HttpApplication上的Init()),如果您在Init()上做了時髦的事情,則會導致間歇性錯誤。

如果您認爲這與EF有關,您可以閱讀如何避免在多線程環境中鎖定(因爲Web應用程序非常多線程,但通常會在生產環境中啓用)。

+0

我應該補充一點,當我在上面遇到這種情況時,我在本地PC上運行,所以我是唯一的用戶,只有一個窗口可以打開應用程序.. – Shayne 2011-02-27 19:34:37

+0

我剛剛意識到一些事情......我們有「httpRuntime executionTimeout」值設置爲「1200」(20分鐘,對吧?)。如果我理解正確,並且問題與請求混淆,我是不是可以降低此值,並且頁面會更快放棄?這是否也會釋放或重置這兩個Web瀏覽器連接之一? – Shayne 2011-02-28 01:19:12

+0

即使您是唯一的用戶,您也可以觸發同時發出的請求,但是它在生產中更常見。執行超時設置爲20分鐘聽起來真的太過分了,所以是的,你可以降低它。然而,你也應該找到問題的根源,因爲即使是很小的鎖定(比如90秒)也會令人討厭,更不用說破壞的功能了。 – jishi 2011-02-28 09:19:57

0

很好,聽起來像應用程序正在等待數據庫操作完成,但已被鎖定可能的,因爲另一個操作。

嘗試使用SQL事件探查器跟蹤活動,並隔離哪些進程正在很長一段時間運行。

您可以在跟蹤查看使用SPID列區分請求時,它包含了從您的應用程序每個會話的唯一ID號。

+0

我應該補充一點這發生在我上面,我在我的本地PC上運行,所以我是唯一的用戶,只有一個窗口打開應用程序.. – Shayne 2011-02-27 19:35:35

+0

這很好,我想也許一個數據庫操作鎖定另一個,即使在單個用戶會話中。 – Menahem 2011-02-28 09:55:09

1

呃,我感覺到你的痛苦 - 我討厭這些類型的問題。下面是當這樣的事情發生了(有點適應您的情況)我的鴻溝正征服過程:

第1步 -

讓自己設立這樣你就可以在你的系統裏面大致看到環境的可見性。設置性能監視器,並添加一些重要的計數器(IIS當前請求,ASP.NET當前請求,SQL Server - 活動事務)。這裏的「主動請求/事務」計數器的想法是你想知道系統的哪一部分正在持有請求。

此外,添加在IIS和DB總請求時間計數器(所以你可以看到它攀爬的東西掛在)。

在您的客戶端PC上設置Fiddler。

第2步 - 重現問題在這一點上

通常,應用程序實現,你可以看到它,並開始完美表現。 ;)停止並確保您仍然可以重現該問題。

第3步 - 以DB的方程

創建應用程序中的4頁:

  1. 靜態HTML文件名(.htm)將不通過ASP.NET運行時去發動機。這是原始IIS的基準。沒有竅門
  2. ASPX頁面(沒有數據庫訪問,沒有處理,只是一個簡單的頁面,ASP.NET可以吐出)
  3. 一個簡單的數據庫調用(有些大小的ASPX頁面,也許做一個大的查詢或東西),還有一些複雜的交易
  4. ASPX頁面(多次查詢等)

第4步 - 重現和測量

因爲這個問題可能會是很明顯的,一旦你可以看到它,找到瓶頸w ith你的表演櫃檯和Fiddler。你的問題聽起來像你可能有一個間歇性的連接問題(無論是客戶端和Web服務器或Web服務器/ SQL),特別是如果IE給你的「頁面無法顯示」的錯誤,但你應該看到在提琴手。在服務器端,您應該看到其中一個性能計數器掛起。

+0

當這發生在我身上......我正在運行LOCAL,SQL,IIS,瀏覽器等...... – Shayne 2011-02-27 20:06:59

+0

你的性能計數器現在說什麼? – Brandon 2011-02-27 20:11:00

+0

我似乎無法找到IIS當前請求計數器......我在「W3SVC_W3P」下看到一個名爲「活動請求」的文件。 (使用IIS 7.5運行Windows 7 64位...)我將在有時使用的虛擬機上運行Fiddler和wb客戶端,以幫助隔離事件,以便我可以更輕鬆地過濾我在SQL Profiler中查找的內容。 – Shayne 2011-02-27 20:37:41

0

我有關於此問題的新信息。

該應用程序使用集成身份驗證。這會導致每次請求都會返回(兩次),並在IE發送憑據之前拒絕訪問。

我不禁想知道這是什麼可能導致「暫停」。

我在每個頁面上實現了一個Ajax「加載」動畫,以防止用戶點擊按鈕,直到前一個請求完成,並大大減少了用戶遇到的「凍結」的數量。

雖然,它還是經常發生。

+0

您可以編輯您的原始問題以包含此信息。這不屬於答覆帖子。 – 2011-05-18 18:20:04

2

我們有同樣的問題,似乎與阿賈克斯添加以下JavaScript來的所有頁面進行修復:

window.onunload = abortRequest; 
function abortRequest() { 
    Sys.WebForms.PageRequestManager.getInstance().abortPostBack(); 
} 

我希望這有助於!

相關問題