When does CallContext LogicalSetData get cleared? Issues with WebApi global ExceptionHandler

我的未来我决定 提交于 2019-12-24 03:18:36

问题


We are implementing a global exception handler for our WebAPI (like in this link)

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

We are also using log4net's LogicalThreadContext to pass around context information (like a call context id or a correlation id). For those of you not familiar, this uses CallContext.LogicalSetData and LogicalGetData.

My problem is that I can't seem to access the data once I get into our custom ExceptionLogger and ExceptionHandler classes. below is a very stripped down / pseduo code of what I mean.

Ideas of why this is happening?

    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:


The problem is not that it is somehow being cleared. Rather, the problem is that CallContext isn't compatible with the "thread agility" model of ASP.NET. At unpredictable intervals, ASP.NET reserves the right to switch threads (leaving CallContext behind).

To compensate, ASP.NET has its own thread-scheduler with its own notion of CallContext, all conveniently wrapped up inside of:

HttpContext.Current.Items[]

If you use that, your values will not "disappear" or act like they were cleared. Furthermore, ASP.NET will automatically release / free the values you put there when the request is complete.

To clarify, when I say "release / free" I mean that the ASP.NET equivalent of CallContext, embodied by HttpContext.Current.Items[], is cleaned up automatically. I do not mean that IDisposable() is called on resources you have placed into HttpContext.Current.Items[]. It is still your duty to handle IDisposables that you allocated.



来源:https://stackoverflow.com/questions/23703464/when-does-callcontext-logicalsetdata-get-cleared-issues-with-webapi-global-exce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!