【问题标题】:When does CallContext LogicalSetData get cleared? Issues with WebApi global ExceptionHandlerCallContext LogicalSetData 什么时候被清除? WebApi 全局 ExceptionHandler 的问题
【发布时间】:2014-05-16 19:48:42
【问题描述】:

我们正在为我们的 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 类,我似乎无法访问数据。下面是我的意思的一个非常精简/伪代码。

为什么会发生这种情况的想法?

    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
            };
    }

【问题讨论】:

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


    【解决方案1】:

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

    作为补偿,ASP.NET 有自己的线程调度器,带有自己的 CallContext 概念,所有这些都方便地封装在:

    HttpContext.Current.Items[]
    

    如果您使用它,您的值将不会“消失”或表现得像被清除了一样。此外,当请求完成时,ASP.NET 会自动释放/释放您放在那里的值。

    澄清一下,当我说“发布/免费”时,我的意思是 ASP.NET 等效的 CallContext(由 HttpContext.Current.Items[] 体现)是自动清理的。我并不是说 IDisposable() 是在您放入 HttpContext.Current.Items[] 的资源上调用的。处理您分配的 IDisposables 仍然是您的职责。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 2012-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多