IISExpress 是单线程的吗?

Is IISExpress Single-Threaded?

我正在编写一个利用安全声明的自定义 .Net 应用程序,因为我们正在跨越许多边界 - 网络、API、批处理等等。在开发过程中,有时我会在通过 Chrome 登录时在系统中创建一些东西,然后我会通过 Edge 中的不同帐户测试新创建的项目,并且以某种方式 HttpContext.Current.User.Identity 对应到我的 Chrome 会话。我确实在幕后设置了 Thread.CurrentPrincipal,但我的理解一直是所有进入 IIS 的请求都会产生一个新线程,所以我无法弄清楚为什么边缘请求被处理,就好像它们是 Chrome 请求。

它共享此信息是否可能是因为 Visual Studio 处于调试模式?

IIS(因此 IISExpress 是以“应用程序”格式打包的 IIS)是多线程的。但是,您做出了一些不正确的假设。

首先,没有。新请求不会产生新线程,它在线程池线程上运行,并且这些线程池在前一个请求完成后被重新使用(或者,正如您稍后将看到的,当异步请求等待时)。

其次,您不应该设置 Thread.CurrentPrincipal,因为 IIS 不仅是多线程的,而且是异步的。这意味着如果您的线程等待,当它恢复时它可能 运行 在与它启动的线程不同的线程上。

第三,Thread.CurrentPrincipal 通常是工作进程(或 AppPool)身份的身份,更改此身份会更改整个线程运行的安全上下文。更好的选择是使用 WindowsImpersonationContext class 进行模拟(我假设您正在尝试这样做)。

WindowsIdentity clientId = (WindowsIdentity)User.Identity;

// When 'using' block ends, the thread reverts back to previous Windows identity,
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose()
using (WindowsImpersonationContext wic = clientId.Impersonate())
{
    // do your work that needs the identity
}

如果您确实需要设置自定义委托人,您通常应该使用 HttpContext.Current.User 而不是 Thread.CurrentPrincipal。