Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >ASP.NET内核中AsyncLocal的安全性

ASP.NET内核中AsyncLocal的安全性
EN

Stack Overflow用户
提问于 2016-04-09 00:11:39
回答 2查看 15.4K关注 0票数 61

对于.NET核心,AsyncLocalCallContext的替代品。然而,目前还不清楚在ASP.NET核心中使用它有多“安全”。

在ASP.NET 4(MVC5)和更早的版本中,thread-agility model of ASP.NET made CallContext unstable。因此,在ASP.NET中,实现每个请求的逻辑上下文行为的唯一安全方法就是使用HttpContext.Current.Items。在幕后,HttpContext.Current.Items是用CallContext实现的,但它是以一种对ASP.NET安全的方式完成的。

相比之下,在OWIN/Katana Web API的上下文中,线程敏捷性模型不是问题。在careful considerations of how correctly to dispose it之后,我能够安全地使用CallContext。

但现在我要处理的是ASP.NET核心。我想使用以下中间件:

代码语言:javascript
运行
AI代码解释
复制
public class MultiTenancyMiddleware
{
    private readonly RequestDelegate next;
    static int random;

    private static AsyncLocal<string> tenant = new AsyncLocal<string>();
    //This is the new form of "CallContext".
    public static AsyncLocal<string> Tenant
    {
        get { return tenant; }
        private set { tenant = value; }
    }

    //This is the new verion of [ThreadStatic].
    public static ThreadLocal<string> LocalTenant;

    public MultiTenancyMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        //Just some garbage test value...
        Tenant.Value = context.Request.Path + random++;
        await next.Invoke(context);

        //using (LocalTenant = new AsyncLocal<string>()) { 
        //    Tenant.Value = context.Request.Path + random++;
        //    await next.Invoke(context);
        //}
    }
}

到目前为止,上面的代码似乎工作得很好。但至少有一个危险信号。在过去,确保将CallContext视为必须在每次调用后释放的资源是至关重要的。

现在我看到没有不言而喻的方法来“清理”AsyncLocal

我加入了代码,注释掉了,展示了ThreadLocal<T>是如何工作的。它是IDisposable,因此它有一个明显的清理机制。相反,AsyncLocal不是IDisposable。这是令人不安的。

这是因为AsyncLocal还没有处于发布候选状态吗?或者这是因为真的不再需要执行清理?

即使我在上面的例子中正确地使用了AsyncLocal,ASP.NET核心中是否有任何老式的“线程敏捷性”问题会使这个中间件无法工作?

特别说明

对于那些不熟悉CallContext在ASP.NET应用程序中存在的问题的人,在this SO post, Jon Skeet中引用了一个in-depth discussion about the problem (而后者又引用了commentary from Scott Hanselman)。这个“问题”不是bug --它只是一个必须仔细考虑的情况。

此外,我可以亲自证明这种不幸的行为。在构建ASP.NET应用程序时,我通常会将负载测试作为自动化测试基础结构的一部分。在负载测试期间,我可以看到CallContext变得不稳定(其中可能有2%到4%的请求显示CallContext被破坏)。我也见过Web API GET具有稳定的CallContext行为,但POST操作都不稳定的情况。实现完全稳定性的唯一方法是依靠HttpContext.Current.Items。

然而,在ASP.NET核心的情况下,我不能依靠HttpContext.Items...there不是这样的静态访问点。我还不能为我正在修补的.NET核心应用程序创建负载测试,这也是我没有回答这个问题的部分原因。:)

:请理解我所讨论的“不稳定性”和“问题”根本不是bug。CallContext并没有什么缺陷。这个问题只是ASP.NET采用的线程分派模型的结果,解决方法很简单,就是知道问题的存在,并进行相应的编码(例如,在ASP.NET应用程序中使用HttpContext.Current.Items而不是CallContext )。

我提出这个问题的目的是理解这种动态如何在ASP.NET核心中应用(或不应用),这样在使用新的AsyncLocal构造时,我就不会意外地构建不稳定的代码。

EN

回答 2

Stack Overflow用户

发布于 2016-05-01 15:53:48

我正在查看CoreClr的ExecutionContext类的源代码:https://github.com/dotnet/coreclr/blob/775003a4c72f0acc37eab84628fcef541533ba4e/src/mscorlib/src/System/Threading/ExecutionContext.cs

根据我对代码的理解,异步本地值是每个ExecutionContext实例的字段/变量。它们不是基于ThreadLocal或任何特定于线程的持久化数据存储。

为了验证这一点,在我对线程池线程的测试中,当相同的线程池线程被重用时,留在异步本地值中的实例是不可访问的,并且“左”实例用于清理自身的析构函数在下一个GC周期中被调用,这意味着该实例如预期的那样是GCed的。

票数 16
EN

Stack Overflow用户

发布于 2020-04-09 12:29:29

如果有人在ASP.NET经典(非核心)应用程序中搜索AsyncLocal是否“安全”后(就像我一样),添加我的两点意见(一些评论者一直在问这个问题,我也看到一个删除的答案询问同样的问题)。

我写了一个模拟ASP.Net的ThreadPool行为的小测试

  1. AsyncLocal 总是在请求之间被清除,即使线程池重新使用了现有的线程。因此,在这一点上是“安全的”,不会将数据泄漏到另一个控制器,即使在相同的上下文中(例如,在global.asax中运行的代码和在thread.
  2. However,中运行的代码之间)也可以清除AsyncLocal。由于MVC方法有时运行在与非MVC代码不同的线程上,请参见以下问题,例如:asp.net mvc 4, thread changed by model binding?
  3. Using ThreadLocal不安全b/c它在线程池中的线程被重用后保留该值。切勿在web应用程序中使用ThreadLocal。我知道问题不是关于ThreadLocal的,我只是向考虑使用它的人添加这个警告,对不起。

在ASP.NET MVC 5 .NET 4.7.2下测试。

总体而言,如果不能直接访问HttpContext.Current中的短时间缓存内容,AsyncLocal似乎是一种完美的替代方案。不过,您最终可能会更频繁地重新计算缓存值,但这不是一个大问题。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36511243

复制
相关文章
在ASP.NET Core中怎么使用HttpContext.Current
  我们都知道,ASP.NET Core作为最新的框架,在MVC5和ASP.NET WebForm的基础上做了大量的重构。如果我们想使用以前版本中的HttpContext.Current的话,目前是不可用的,因为ASP.NET Core中是并没有这个API的。
yoyofx
2018/09/05
3K0
从 ThreadLocal 到 AsyncLocal
前些天跟大佬们在群里讨论如何在不使用构造函数,不增加方法参数的情况下把一个上下文注入到方法内部使用,得出的结论是 AsyncLocal 。感叹自己才疏学浅,居然才知道有 AsyncLocal 这种神器。于是赶紧恶补一下。
MJ.Zhou
2021/11/18
5540
内核中的宏
宏是一种抽象(Abstraction),它根据一系列预定义的规则替换一定的文本模式。解释器或编译器在遇到宏时会自动进行这一模式替换。在linux中大量的使用宏,使得代码简洁且技巧性很高,本篇就主要记录一下在linux中比较常用的几种用法。
开源519
2020/07/23
1.9K0
采用”传统”方式获取当前HttpContext
我们知道“依赖注入”已经成为了.NET Core的基本编程模式,表示当前请求上下文的HttpContext可以通过注入的IHttpContextAccessor服务来提取。有时候我们会使用一些由于某些原因无法使用依赖注入的组件,我们如何提取当前HttpContext呢?
蒋金楠
2020/11/24
6270
Android Q 中的安全性更新
每次发布 Android 的新版本,我们的首要任务之一就是提高平台的安全防护。在过去几年,安全方面的优化在整个生态圈都取得了喜人的成绩,2018 年亦是如此。
Android 开发者
2019/06/04
7810
Windows内核中的内存管理
其中PAGED_CODE是一个WDK中提供的一个宏,只在debug版本中生效,用于判断当前的中断请求级别,当级别高于DISPATCH_LEVEL(包含这个级别)时会产生一个断言
Masimaro
2018/08/31
1.4K0
Linux内核中的printf实现
参数中明显采用了可变参数的定义,而在main.c函数的后面直接调用了printf函数,我们可以看下printf函数的参数是如何使用的。
范蠡
2018/07/25
2.4K0
Linux内核源代码情景分析-访问权限与文件安全性
在Linux内核源代码情景分析-从路径名到目标节点,一文中path_walk代码中,err = permission(inode, MAY_EXEC)当前进程是否可以访问这个节点,代码如下: int permission(struct inode * inode,int mask) { if (inode->i_op && inode->i_op->permission) { int retval; lock_kernel(); retval = inode->i_op->permission(ino
小小科
2018/05/04
2.7K0
Linux内核源代码情景分析-访问权限与文件安全性
API网关在API安全性中的作用
从单一应用程序切换到微服务时,客户端的行为不能与客户端具有该应用程序的一个入口点的行为相同。简单来说就是微服务上的某一部分功能与单独实现该应用程序时存在不同。
架构师修炼
2020/07/20
1.4K0
API网关在API安全性中的作用
探究Spring中Bean的线程安全性问题
  今天同事笑嘻嘻的凑过来,问了我一个问题:spring中的bean是线程安全的吗?。我内心一想肯定是安全的,毕竟这样多项目在用。但是转念一想,他那贱兮兮的表情,多半是在给我挖坑。于是我自信的回答他:不安全。他反问,你确定😏?
不一样的科技宅
2023/09/01
2820
探究Spring中Bean的线程安全性问题
Linux内核中的递归漏洞利用
6月1号,我提交了一个linux内核中的任意递归漏洞。如果安装Ubuntu系统时选择了home目录加密的话,该漏洞即可由本地用户触发。如果想了解漏洞利用代码和短一点的漏洞报告的话,请访问https:/
FB客服
2018/02/08
2.2K0
Linux内核中的递归漏洞利用
【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )
Android 内核源码地址 : https://android.googlesource.com/kernel/
韩曙亮
2023/03/29
1K0
【Binder 机制】分析 Android 内核源码中的 Binder 驱动源码 binder.c ( googlesource 中的 Android 内核源码 | 内核源码下载 )
asp.net中的联动菜单
目标达到的效果:两个下拉框,第二个跟随第一个变化而变化,使用客户端脚本JavaScript在ASP.NET环境下实现。
Java架构师必看
2021/03/22
1.4K0
浅析linux内核中的idr机制
idr在linux内核中指的就是整数ID管理机制,从本质上来说,这就是一种将整数ID号和特定指针关联在一起的机制。这个机制最早是在2003年2月加入内核的,当时是作为POSIX定时器的一个补丁。现在,在内核的很多地方都可以找到idr的身影。
全栈程序员站长
2022/07/18
1.9K0
ASP.NET中DropDownList 的使用
AppendDataBoundItems:为是否填加重复值。真为添加,假为不填加 将DropDownList控件中AppendDataBoundItems属性设置为“False”即可。
全栈程序员站长
2022/11/02
1.4K0
多线程下的调用上下文 : CallContext
最近在分析现在团队的项目代码(基于.NET Framework 4.5),经常发现一个CallContext的调用,记得多年前的时候用到了它,但是印象已经不深刻了,于是现在来复习一下。
Edison Zhou
2021/06/24
9510
ASP.NET中的几种分页
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/39644255
DannyHoo
2018/09/13
2.7K0
ASP.NET中的几种分页
ASP.NET Core 中的 ServiceProvider
在 ASP.NET Core 中,微软提供了一套默认的依赖注入实现,该实现对应的包为:Microsoft.Extensions.DependencyInjection,我们可以通过查看其对应的开源仓库看一下它的具体实现。基于该实现,我们不必显式创建我们的服务对象,可以将其统一注入到 ServiceProvider 中进行集中维护,使用的时候直接在该对象中获取即可。让我们在编写业务逻辑时,不用太关注对象的创建和销毁。这也是为什么现在有些最佳实践中建议不要过多使用 New 的方式来获取对象。在本文中,我们将一起了解一下如何实现一个自己的 ServiceProvider。
AI.NET 极客圈
2019/08/29
1.9K0
ASP.NET Core 中的 ServiceProvider
ASP.NET Core中的Controller
ASP.NET CORE出现之前我们实现的Controller,MVC都继承自Controller基类,WebApi的话继承自ApiController。现在ASP.NET CORE把MVC跟WebApi合并了,已经不再区分MVC或者WebApi。ASP.NET CORE的Controller继承结构也发生了变化。我们看其他示例的时候会发现有些继承自Controller有些继承自ControllerBase。事实上ControllerBase是Controller的基类。也就是说如果你继承自Controller,其实就是继承了ControllerBase。那什么时候该选择直接继承ControllerBase呢?
MJ.Zhou
2020/04/13
1.7K0
点击加载更多

相似问题

带有AsyncLocal核心控制器/ServiceProviderScope的ASP.NET

11

如何访问AsyncLocal

10

AsyncLocal格式的环境数据

153

修改存储在AsyncLocal中的对象

12

.Net内核中的postgresql行级安全性

110
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档