2009-12-21 47 views
5

我有一個Web應用程序嚴重依賴Web服務。與服務的所有內容都是異步完成的,並且使用AddOnPreRequestHandlerExecuteAsync。無論如何,我的大部分調用都可以正常工作,但有些從他們的異步服務調用中返回,以便在endprerequest中找到一個空的HttpContext.Current.Response/Request對象,當然我嘗試使用這兩個對象。兩個對象(響應和請求在開始預請求失敗呼叫時可用/不爲空,並且在其他呼叫的結束請求中工作)。異步HttpWebRequests和null HttpContext.Current.Response /請求對象

任何人都會遇到類似的情況,或猜測可能是什麼問題?

更新:似乎已經找到了一個解決方案,如果我爲init上的HttpApplication創建一個變量(HttpModule全部出現),可以從該變量訪問HttpContext。

更新:在begin函數上傳遞HttpApplication或HttpContext.Current具有相同的問題。當作爲異步調用的「狀態」的一部分傳遞時,即使它們在begin函數中有效,它們也會在end函數中結束爲null。

更新:我添加了一些日誌記錄,發現我所做的異步調用正確返回,結果在那裏,回調函數調用正確。

回答

0

似乎找到了一個解決方案,如果我爲init上的HttpApplication創建了一個變量(HttpModule全部出現),那麼可以從該變量訪問HttpContext。

+0

你能詳細描述你是如何解決問題的 – omoto 2010-01-30 17:35:10

+0

在我的HttpModule中,我有一個類型爲HttpApplication的變量。在init()函數調用中,我將此變量設置爲傳遞給init的HttpApplication。在BeginPreRequestHandlerExecute和EndPreRequestHandlerExecute中,我使用oApplication.Context引用當前的HttpContext,oApplication是HttpModule中HttpApplication變量的名稱。 – aepheus 2010-02-02 19:07:04

5

我懷疑我知道你遇到的問題。答案几乎可以肯定的是,將HttpWebRequest的使用替換爲WebClient,並使用WebClient的*異步方法。

以下是長長的解釋:有兩種完全不同的Async編程模型:IAsyncResult Async PatternEvent-based Asynchronous Pattern。 IAsyncResult模式使用BeginXXXEndXXX方法,使用IAsyncResult實例,使用委託進行回調,並支持等待完成。基於事件的模式使用XXXAsync方法來啓動異步操作,使用XXXCompleted事件而不是回調來處理完成,並且(這對您的案例很重要)將線程特定的上下文轉移到每個回調事件處理程序中。換句話說,如果您將回調代碼放入XXXCompleted事件處理程序(如WebClient.DownloadStringCompleted)中,則HttpContext.Current將正確填充。

但是,如果您使用BeginXXX方法(如HttpWebRequest.BeginGetResponse)和委託回調,則您的回調將在不保證有正確的ASP.NET上下文連接的線程的上下文中執行。

通常,.NET Framework庫類使用一個異步模式或其他。通常,較低級別的類(例如HttpWebRequest)將使用IAsyncResult模式,而較高級別的類(例如WebClient)將使用基於事件的模式。一些奇怪的類(例如自動生成的.NET Remoting代理)將支持這兩種模式,但這是罕見的。

所以,如果很容易做到,我建議轉移到WebClient和事件處理程序而不是HttpWebRequest和回調委託。這應該可以解決你的問題。如果切換到WebClient太難了,評論和我可能會建議一些更晦澀的替代品。

+0

我不知道這將是多麼容易實施在我的情況。我相信我至少在基本級別綁定了IAsyncResult模式,因爲這是AddOnPreRequestHandlerExecuteAsync支持的模式。而且,由於我現在只需將狀態保存在一個變量中,所以我不想惹它。 – aepheus 2010-01-05 16:44:36