.net CallContext LogicalSetData何时清除?WebApi全局异常处理程序的问题
我们正在为我们的WebAPI实现一个全局异常处理程序(如本链接中所示) 我们还使用log4net的LogicalThreadContext传递上下文信息(如调用上下文id或关联id)。对于不熟悉的用户,这将使用CallContext.LogicalSetData和LogicalGetData 我的问题是,一旦进入自定义ExceptionLogger和ExceptionHandler类,我似乎就无法访问数据。下面是我的意思的一个非常精简的/psedou代码 为什么会发生这种情况.net CallContext LogicalSetData何时清除?WebApi全局异常处理程序的问题,.net,asp.net-web-api,exception-handling,.net,Asp.net Web Api,Exception Handling,我们正在为我们的WebAPI实现一个全局异常处理程序(如本链接中所示) 我们还使用log4net的LogicalThreadContext传递上下文信息(如调用上下文id或关联id)。对于不熟悉的用户,这将使用CallContext.LogicalSetData和LogicalGetData 我的问题是,一旦进入自定义ExceptionLogger和ExceptionHandler类,我似乎就无法访问数据。下面是我的意思的一个非常精简的/psedou代码 为什么会发生这种情况 publ
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留在后面) 作为补偿,ASP.NET有自己的线程调度程序,它有自己的CallContext概念,所有这些都方便地包装在:
HttpContext.Current.Items[]
如果您使用它,您的值将不会“消失”或像被清除一样。此外,ASP.NET将在请求完成时自动释放/释放您在其中输入的值
为了澄清,当我说“release/free”时,我的意思是由HttpContext.Current.Items[]体现的与CallContext相当的ASP.NET自动清除。我并不是说对您放入HttpContext.Current.Items[]的资源调用IDisposable()。处理分配的IDispobles仍然是您的职责