CallContext LogicalSetData什么时候被清除? WebApi全局ExceptionHandler的问题

时间:2014-05-16 19:48:43

标签: .net asp.net-web-api exception-handling

我们正在为我们的WebAPI实现一个全局异常处理程序(就像在这个链接中一样)

  

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 个答案:

答案 0 :(得分:1)

问题不在于它以某种方式被清除。相反,问题是CallContext与"线程敏捷性并不相容。 ASP.NET模型。在不可预测的时间间隔内,ASP.NET保留切换线程的权利(将CallContext留在后面)。

为了弥补这一点,ASP.NET有自己的线程调度程序,它有自己的CallContext概念,所有这些都很方便地包含在:

HttpContext.Current.Items[]

如果你使用它,你的价值观就不会消失了#34;或表现得像他们被清除。此外,ASP.NET将在请求完成时自动释放/释放您放在那里的值。

澄清一下,当我说"释放/免费"我的意思是由HttpContext.Current.Items []体现的ASP.NET等效的CallContext被自动清理。我并不是说在你放入HttpContext.Current.Items []的资源上调用了IDisposable()。您仍然有责任处理您分配的IDisposable。