找到演示此问题的完整示例应用here。
我正在尝试使用OWIN中间件来填充可通过WebForms页面访问的静态标识符,但是我注意到,对于某些类型,它不能直观地表现-特别是AsyncLocal<T>
。
使用int
,考虑以下工作示例:
简单的静态容器
public static class Container
{
public static int CallId { get; set; }
}
简单的OWIN配置
[assembly: OwinStartup(typeof(Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
Container.CallId = 5;
return next.Invoke();
});
}
}
简单的Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Container.CallId != 5)
{
throw new Exception("What happened to CallId");
}
}
此功能按预期运行。中间件将CallId
设置为5,WebForms页面看到5。不会引发异常。
这是打破直觉的地方,如果我想对我的CallId使用AsyncLocal<int>
,则该值在WebForms页面中不再可用。例如
损坏的容器
public static class Container
{
public static AsyncLocal<int> CallId { get; set; }
}
OWIN配置损坏
[assembly: OwinStartup(typeof(Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Use((context, next) =>
{
AsyncLocal<int> asyncId = new AsyncLocal<int>();
asyncId.Value = 5
Container.CallId = asyncId;
return next.Invoke();
});
}
}
损坏的Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (Container.CallId.Value != 5)
{
throw new Exception("What happened to CallId");
}
}
这不会不能正常运行。标识符在中间件中创建,但在页面中不可用。 引发异常。
为什么?
我正在努力拼凑为什么此更新会破坏直觉;我想不出任何可能导致价值消失的东西。
On_Load
之间,进程,域和线程ID均保持不变。 Container
是静态的,因此域中仅存在一个实例。 MyType
尝试过同样的事情,CallId
在WebForm中不会返回null
静态CallId
值去哪里了?
如果您想亲自看看,这里是demo github repo。
答案 0 :(得分:0)
您使用错误。使用本地变量保存所需的值。
public static class Container {
private static AsyncLocal<int> current = new AsyncLocal<int>();
public static int CallId {
get {
return current.Value;
}
set {
current.Value = value;
}
}
}
OWIN配置保持不变。
[assembly: OwinStartup(typeof(Startup))]
public class Startup {
public void Configuration(IAppBuilder app) {
app.Use((context, next) => {
Container.CallId = 5;
return next.Invoke();
});
}
}
AsyncLocal<T>
类现在将在跨线程的异步流中保留该值。