问题描述
我们正在为WebAPI实现全局异常处理程序(如此链接中所示)
We are implementing a global exception handler for our WebAPI (like in this link)
我们还使用log4net的LogicalThreadContext传递上下文信息(例如调用上下文ID或相关ID)。对于不熟悉的人,它使用CallContext.LogicalSetData和LogicalGetData。
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.
我的问题是,一旦进入自定义的ExceptionLogger,我似乎就无法访问数据。和ExceptionHandler类。下面是我的意思很精简的/伪代码。
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.
为什么会这样?
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
};
}
推荐答案
问题不在于此被以某种方式清除了。相反,问题在于CallContext与ASP.NET的线程敏捷性模型不兼容。在不可预测的时间间隔内,ASP.NET保留切换线程的权利(将CallContext留在后面)。
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).
为了弥补这一点,ASP.NET拥有自己的线程调度器和自己的概念的CallContext,都方便地封装在以下内容中:
To compensate, ASP.NET has its own thread-scheduler with its own notion of CallContext, all conveniently wrapped up inside of:
HttpContext.Current.Items[]
如果使用它,您的值将不会消失或像被清除一样起作用。此外,ASP.NET将在请求完成后自动释放/释放您放置在其中的值。
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.
为了澄清,当我说释放/释放时,我的意思是会自动清除由HttpContext.Current.Items []实现的与CallContext等效的ASP.NET。我并不是说要对放置在HttpContext.Current.Items []中的资源调用IDisposable()。处理分配给您的IDisposable仍然是您的责任。
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.
这篇关于何时清除CallContext LogicalSetData? WebApi全局ExceptionHandler的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!