2012-09-25 95 views
3

最近我們開始看到一個問題,其中的Application_Error事件處理程序(對於HttpApplication.Error)在與處理請求的其他線程上進行調用。Application_Error在不同的線程上觸發

的事情,我們最近做了更改:

  • 32位到64位
  • 經典到綜合管線模式

爲了什麼它的價值,這裏的一些代碼,這可能有助於解釋這一點:
在一個代表性測試中,頁面上顯示的線程爲7,其中電子郵件中的線程爲10.

//The application 
public class MyApplication : HttpApplication 
{ 
    protected virtual void Application_Error(ByVal sender As Object, ByVal e As EventArgs) 
    { 
     var threadId = System.Threading.Thread.Current.ManagedThreadId; 
     SendEmail("There was an error on threadId " + threadId.ToString()); 
    } 

    private void SendEmail(string message) 
    { 
     //snip 
    } 
} 

//Some aspx page 
<% 
var threadId = System.Threading.Thread.Current.ManagedThreadId; 
throw new Exception("This is a test. ThreadId = " + threadID.ToString()); 
%> 

這會給我們帶來問題,因爲我們在Thread.CurrentPrincipal中存儲身份驗證信息,我們需要記錄該例外的信息。

我該如何保持它在同一個線程上,或者讓IIS從原始線程向我提供CurrentPrincipal?

+0

這是因爲那是錯誤被拋出的線程。什麼是被拋出的異常? – Justin

+0

@Justin我認爲你誤解了。這可能是任何異常,並且引發異常的線程與正在觸發Application_Error的線程不同。這用於在應用程序中記錄任何未處理的異常。 – csauve

+0

嗯...爲什麼你需要threadID是一樣的?我建議通過詢問實際問題來澄清您的問題。到目前爲止,你所做的只是說「我看到了這種行爲」,不要告訴我爲什麼這很重要,或者你的實際問題在我的問題中是 – Earlz

回答

2

我假設你看到這種行爲,因爲ASP.Net使用不同的線程來執行ASP.Net頁面並處理錯誤。

您應該能夠通過使用HttpContext.Current.User來解決您的問題。但是,這些之間可能存在細微的差異。您可以檢查this文章,說明他們可以指向不同的對象(但基本上只有當你這樣做時纔會這樣做)

+0

有趣。我會嘗試一下! – csauve

+0

不幸的是,Request.Context.Current.User只是一個GenericPrincipal。請注意,我們正在尋找的Principal是我們通過自己的身份驗證機制向Thread.CurrentPrincipal推送的,而不是經過IIS身份驗證的用戶。 – csauve

+1

那麼最大的問題是爲什麼你推動線程,而不是請求..我提到的博客文章基本上說,讓這些不同步是一個不好的做法 – Earlz

相關問題