2014-05-16 40 views
1

我們正在實現我們的WebAPI一個全球性的異常處理程序(如在此鏈接)問題什麼時候CallContext LogicalSetData被清除?用的WebAPI全球的ExceptionHandler

http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling

我們還利用log4net的的LogicalThreadContext以繞過上下文信息(如呼叫上下文ID或相關ID)。對於那些你不熟悉的,這使用CallContext.LogicalSetData和LogicalGetData。

我的問題是,我似乎無法訪問數據,一旦我進入我們的自定義ExceptionLogger和ExceptionHandler類。下面是我的意思是一個非常簡潔/ pseduo代碼。

想法爲什麼發生這種情況?

public MyResponse Get(string someId) 
    { 
     CallContext.LogicalSetData("mytest", "555"); 
     LogicalThreadContext.Properties["anotherprop"] = "999"; 

     string contextValue = CallContext.LogicalGetData("mytest") as string; 
     string contextValue2 = LogicalThreadContext.Properties["anotherprop"] as string; 
     throw new Exception("Fake exception that I am logging"); 
    } 


public class HttpExceptionLogger : ExceptionLogger 
{ 
    public override void LogCore(ExceptionLoggerContext context) 
    { 
     // PROBLEM: this is null 
     string contextValue = CallContext.LogicalGetData("mytest") as string; 

     // this is okay, returns '999' 
     string contextValue2 = LogicalThreadContext.Properties["anotherprop"] as string; 
     // do some logging, etc. 
    } 

public class HttpExceptionHandler : ExceptionHandler 
{ 
    public override void HandleCore(ExceptionHandlerContext context) 
    { 
     // PROBLEM: this is null 
     string contextValue = CallContext.LogicalGetData("mytest") as string; 

     // PROBLEM: this is also null 
     string contextValue2 = LogicalThreadContext.Properties["anotherprop"] as string; 

     // return a message to the user, e.g. 
     string message = string.Format("unexpected exception, ref Id={0}, ref Id2={1}", contextValue, contextValue2); 
     context.Result = new TextPlainExceptionResult 
      { 
       Request = context.ExceptionContext.Request, 
       Content = message 
      }; 
    } 

回答

1

問題不是它以某種方式被清除。相反,問題在於CallContext與ASP.NET的「線程敏捷性」模型不兼容。在不可預測的時間間隔內,ASP.NET保留切換線程的權利(將CallContext留下)。

爲了彌補,ASP.NET都有自己的線程調度器有自己的CallContext中的概念,所有的便利,裏面包裹起來:

HttpContext.Current.Items[] 

如果你使用,你的價值觀不會「消失」或像他們被清除一樣行事。此外,ASP.NET會在請求完成時自動釋放/釋放您放入的值。

爲了澄清,當我說「release/free」時,我的意思是CallContext的ASP.NET等價物,由HttpContext.Current.Items []體現,自動清理。我不是說在您放入HttpContext.Current.Items []的資源上調用了IDisposable()。處理您分配的IDisposables仍然是您的責任。

相關問題