这里有很多展示 - 但它是必要的。
不知道有多少人知道这一点,但是,Visual Studio 中的 Razor 代码编辑器会导致您的网站在Application_Start
事件之前被“测试”——这在我当前的项目中造成了一些烦人的问题,它使用WebActivator 做了很多网站初始化。
更新 - 仔细检查它不仅仅是 Razor - 它看起来像是 Visual Studio 范围的 - 因此标题的变化
我需要能够检测网站代码何时由 Visual Studio 而不是由 Web 服务器运行。
为了演示 - 执行以下操作(完全按照书面说明以确保其重现):
- 创建一个新的 MVC 4 站点,我使用了 Internet 应用程序模板,因此创建时有一些页面。
- 从 nuget 添加 WebActivator 包
- 将一个类添加到 App_Start 文件夹,名为
RazorPageBugTest
- 粘贴此代码(更改相关的命名空间):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcApplication6.App_Start;
using System.IO;
[assembly: WebActivator.PreApplicationStartMethod(
typeof(RazorPageBugTest), "Start", Order = 0)]
namespace MvcApplication6.App_Start
{
public static class RazorPageBugTest
{
public static void Start()
{
using (var writer = File.Open(@"c:\trace.txt", FileMode.Create))
{
using (var tw = new StreamWriter(writer))
{
tw.AutoFlush = true;
tw.WriteLine("Written at {0}", DateTime.Now);
}
}
}
}
}
请注意,此代码无论如何通常都不能在 Web 服务器上运行 - 考虑到它正在写入驱动器 C:(如果您不以管理员身份运行 VS,这实际上可能无法在您的计算机上运行)。
- 现在构建项目。
- 如果您已经在 C 上打开了资源管理器,则下一点效果最好:完成后,找到 Razor 视图并打开它
- 等待所有 C#/VB 位被突出显示
- 看一下驱动器 C - 哦,看,有一个名为“trace.txt”的文件,日期在最后几秒钟内!
这说明了这里的问题 - Razor 代码编辑器正在启动 AppDomain,并且有效地对网站进行炮击以获得智能感知(包括 App_Helpers 文件夹中的内容等)。现在它实际上并没有触发该Application_Start
方法 - 但是当您在项目中也有 WebActivator 时,它的任何应用程序启动前方法都会被触发。
在我的情况下,这会导致巨大的问题 - 高 CPU 使用率和内存使用率devenv.exe
(相当于刚刚启动的网站),因为我初始化了 DI 容器并且天知道此时还有什么,但一个特别是证明真的很烦人。
我的网站有一个组件,它在网络上侦听来自网络场中其他机器的状态和缓存无效消息。在 QA 和 Live 环境中,这个监听器永远不会打开端口并监听 - 但是,在我的开发机器上,它经常失败 - 说端口已经在使用中。当我寻找保持它打开的过程时 - 它总是devenv.exe
.
你猜对了——我在一个 WebActivator 初始化的引导调用中启动了这个监听器。
所以问题是 - 有没有人知道一种方法来检测代码不是由“适当的”网络主机运行的,所以我可以阻止它运行?我对此特别充满希望,因为这也意味着我的 Visual Studio 和 Razor 编辑体验将因此更快地成为该死的网站!
作为奖励,任何修复都可以合法地发送给 WebActivator 的作者 David Ebbo,这样他就可以更早地将其粘贴到他的堆栈中以完全防止问题发生!
更新
我刚刚在 GitHub 上的 WebActivator 页面上添加了一个问题,以查看 David Ebbo 是否可以将我的修复或更好的修复推送到 WebActivator 组件中。