C# 检测Visual Studio何时为intellisense测试启动网站
这里有很多解释,但这是必要的 不知道有多少人知道这一点,但是,Visual Studio中的Razor代码编辑器会导致您的网站在C# 检测Visual Studio何时为intellisense测试启动网站,c#,asp.net-mvc-3,visual-studio-2010,razor,asp.net-mvc-4,C#,Asp.net Mvc 3,Visual Studio 2010,Razor,Asp.net Mvc 4,这里有很多解释,但这是必要的 不知道有多少人知道这一点,但是,Visual Studio中的Razor代码编辑器会导致您的网站在应用程序启动之前被“测试启动”事件-这会在我当前的项目中造成一些恼人的问题,该项目使用WebActivator进行大量的网站初始化 更新-仔细观察,它不仅仅是剃须刀-它看起来像是Visual Studio范围内的-因此更改了标题 我需要能够检测网站代码何时由VisualStudio而不是web服务器运行 演示-按照书面要求执行以下操作(准确地执行),以确保其再现: 创
应用程序启动之前被“测试启动”
事件-这会在我当前的项目中造成一些恼人的问题,该项目使用WebActivator进行大量的网站初始化
更新-仔细观察,它不仅仅是剃须刀-它看起来像是Visual Studio范围内的-因此更改了标题
我需要能够检测网站代码何时由VisualStudio而不是web服务器运行
演示-按照书面要求执行以下操作(准确地执行),以确保其再现:
- 创建一个新的MVC4站点,我使用了Internet应用程序模板,因此在创建时有一些页面
- 从nuget添加WebActivator包
- 将名为
RazorPageBugTest
- 粘贴此代码(更改相关命名空间):
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Web;
使用mvcapapplication6.App_启动;
使用System.IO;
[组件:WebActivator.PreApplicationStartMethod(
类型(RazorPageBugTest),“开始”,顺序=0)]
名称空间MVCAPApplication6.App_开始
{
公共静态类RazorPageBugTest
{
公共静态void Start()
{
使用(var writer=File.Open(@“c:\trace.txt”,FileMode.Create))
{
使用(var tw=新的StreamWriter(writer))
{
tw.AutoFlush=true;
tw.WriteLine(“写在{0}”,DateTime.Now);
}
}
}
}
}
请注意,这段代码通常不会在web服务器上运行,因为它正在写入驱动器C:(如果您不以管理员身份运行VS,这可能在您的计算机上不起作用)
- 现在构建项目
- 如果您已经在C上打开了资源管理器,那么下一步的工作效果最好:完成后,找到一个Razor视图并打开它
- 等待所有C#/VB位高亮显示
- 看看驱动器C-哦,看,有一个名为“trace.txt”的文件,日期在最后几秒钟内李>
应用程序启动
方法,但是当项目中也有WebActivator时,它的任何应用程序启动前方法都会被触发
在我的例子中,这导致了巨大的问题-在devenv.exe中的CPU使用率和内存使用率很高(相当于刚刚启动的网站),因为我初始化了DI容器,上帝知道在这一点上还有什么,但有一个特别令人讨厌
我的网站有一个组件,它在网络上侦听状态并缓存来自web场中其他机器的无效消息。在QA和实时环境中,此侦听器从不失败地打开端口并侦听—在我的开发人员机器上,它经常失败—表示端口已在使用中。当我寻找保持它打开的进程时,它总是devenv.exe
你猜对了-我在WebActivator初始化的引导调用中启动了这个侦听器
所以问题是——有没有人知道一种方法可以检测到代码不是由“适当”的web主机运行的,这样我就可以停止它的运行?我对此特别有希望,因为这也意味着我的VisualStudio和Razor编辑体验将因此更快地成为一个该死的网站
作为奖励,任何修复程序都可以合法地发送给WebActivator的作者David Ebbo,这样他就可以将其更早地粘贴到堆栈中,以完全防止出现问题
更新
我刚刚添加了一个测试,看看David Ebbo是否可以将我的补丁或更好的补丁推到WebActivator组件中 猜猜在这种情况下,Process.GetCurrentProcess().ProcessName
的值是多少
回答:Microsoft.VisualStudio.Web.Host
因此,如果流程名称中有VisualStudio
,您可以安全地将其删除
另外,请查看有关托管过程的信息。而Darin关于托管过程的信息是正确的-从我所看到的情况来看,这仅适用于VS2012。早期版本的VS主机直接位于devenv内部
由于我在这里有一个nuget包堆栈,所以我将此扩展方法放入我们的Web核心组件中,该组件合并到WebActivator
命名空间中:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace WebActivator
{
public static class HostInformation
{
private static readonly string[] _knownDevEnvironments = new[] {
"devenv",
"microsoft.visualstudio.web.host"
};
private static Lazy<bool> _isDevelopmentEnvironment = new Lazy<bool>(
() => _knownDevEnvironments.Any(
s => s.Equals(Process.GetCurrentProcess().ProcessName,
StringComparison.OrdinalIgnoreCase)
));
/// <summary>
/// Returns true if the current hosting environment is a known
/// development environment instead of a web server or similar.
///
/// This is used to decide whether or not to actually run
/// pre-application-start methods which are undesirable to
/// run in the development environment.
/// </summary>
/// <returns></returns>
public static bool IsDevelopmentEnvironment
{
get
{
return _isDevelopmentEnvironment.Value;
}
}
}
}
因此,所有的启动方法都可以更早地退出
老实说,我讨厌这个解决方案,但出于同样的原因,没有更简单的方法
另一方面,我的VS(2010年和2012年)现在非常快地向我展示了intellisense的Razor文件;不会在内存中大量增长,更重要的是,永远不会占用该网络端口…您可以使用System.Web.Hosting.HostingEnvironment.InClientBuildManager
,而不是编写自己的逻辑来检测此问题,无论是VS运行该代码还是在aspnet\u compiler.exe中运行,这都是正确的
有关此问题的更多详细信息,请参阅此部分。很有趣-我有一个修复程序(在回来检查答案之前,我刚刚实现了它);但在我的例子(Visual Studio 2010)中,Process.GetCurrentProcess().ProcessName
的值实际上是devenv
,这肯定不是托管进程,因为网站想要使用的网络端口总是由devenv获取的——检查进程名称仍然是我知道的最好的方法,尽管如此,还是把它作为答案,因为没有比检查流程更好的方法了
if(HostInformation.IsDevelopmentEnvironment)
return;