如何在ASP.NET应用程序中初始化
如何在ASP.NET应用程序中初始化
发布时间:2015-06-12 来源:查字典编辑
摘要:每个程序都需要初始化的过程,用来读取配置或者设置一些运行环境(变量),对于程序来说,又该在哪里执行初始化的任务呢?我想应该绝大多数人都知道在...

每个程序都需要初始化的过程,用来读取配置或者设置一些运行环境(变量),对于程序来说,又该在哪里执行初始化的任务呢?

我想应该绝大多数人都知道在Global.asax中执行初始化的过程,然而有些细节是我们需要关注的。

本文用例

在这篇博客的示例代码中,AppInitializer包含了网站的初始化的实现代码:

public static class AppInitializer { public static ConnectionStringSettings MyNorthwindConnectionSetting { get; private set; } public static void Init() { // 读取连接字符串。 LoadConnectionString(); // 设置SQLSERVER缓存依赖通知。 SetSqlDependency(); // 其它的初始化操作。 OthersInit(); } static void LoadConnectionString() { ConnectionStringSettings setting = ConfigurationManager.ConnectionStrings["MyNorthwind"]; if( setting == null ) throw new ConfigurationException("没有配置MyNorthwind连接字符串。"); if( string.IsNullOrEmpty(setting.ConnectionString) ) throw new ConfigurationException("没有为MyNorthwind连接字符串指定内容。"); if( string.IsNullOrEmpty(setting.ProviderName) ) throw new ConfigurationException("没有为MyNorthwind连接字符串指定ProviderName 。"); // 保存读取到的连接字符串,供程序使用。 MyNorthwindConnectionSetting = setting; } static void SetSqlDependency() { // 判断SQLSERVER版本是否为 2005以上版本, // 是否开启Service Broker的检查代码就不列出了。 SqlDependency.Start(MyNorthwindConnectionSetting.ConnectionString); } static void OthersInit() { // 其它的初始化操作。 // 例如: // 1. 加载必要的缓存数据。 // 2. 检查上传目录是不存在。 // 3. ................... } }

这段代码的意图很清楚,一定要确保正确的配置了数据库连接字符串,否则以异常的形式报告出来。

示例程序还有一个页面,Default.aspx

<body> <form id="form1" runat="server"> <div> <h1>User Login</h1> </div> <p style="line-height: 150%;"> UserName: <asp:TextBox ID="txtUserName" runat="server" Width="200px" Text="Fish Li"></asp:TextBox><br /> Password: <asp:TextBox ID="txtPassword" runat="server" Width="200px" TextMode="Password"></asp:TextBox><br /> <asp:Button ID="btnLogin" runat="server" Text="登录" OnClick="btnLogin_Click" /> </p> </form> </body>

其实就是一个登录页面,后台代码为:

protected void btnLogin_Click(object sender, EventArgs e) { bool ok = false; using( SqlConnection connection = new SqlConnection(AppInitializer.MyNorthwindConnectionSetting.ConnectionString) ) { connection.Open(); // 其它的数据库操作。 ok = true; } if( ok ) Response.Redirect("Default2.aspx"); }

你没有想到的Global.asax怪事!

或许有些人会这样写他们的初始化代码:

void Application_Start(object sender, EventArgs e) { //在应用程序启动时运行的代码 try { AppInitializer.Init(); } catch( Exception ex ) { LogException(ex); // ..................... } }

这段代码有什么问题呢?

其实问题的线索在于:为什么要加try....catch语句,是因为知道可能会发生异常吗?

如果真有异常情况发生,这样处理后,后续的请求是不是会发生各种想像不到的错误?

显然这里不能吃掉异常,要不然后面的请求肯定会有问题,因为它们依赖的设置没有正确的初始化。

好吧,那我去掉 try.....catch语句,这样总该行了吧:

void Application_Start(object sender, EventArgs e) { //在应用程序启动时运行的代码 AppInitializer.Init(); }

还是看来一下真实的运行情况吧。

如何在应用程序中初始化1

噢,抱歉,我还真忘记了配置连接字符串,这个异常提示太给力了。

现在就加上连接字符串吗?

别急,想像一下,如果这个网站是一个真实的在线网站,会是什么情况呢?
答案有二种:

1. 另一个用户也发起了一次请求。

2. 当前用户看到错误页面后,重新刷新了一次当前页面。

现在我用Opera来扮演第二个浏览用户吧,还是打开同样的网址。

如何在应用程序中初始化2

太奇怪了,第二个用户居然能打开页面,好吧,让他登录试试。

如何在应用程序中初始化3

结果第二个用户看到的错误情况和第一个用户完全不同。

如果此时第一个用户刷新他的浏览器,发现页面又可以显示了,然而登录时,会看到与第二个用户一样的异常信息。

这个示例代码实在太简单了,我想维护人员根据NullReferenceException这个线索找下去,很快就能找到答案。如果初始化代码再复杂一些,比如SetSqlDependency()中出现异常呢,那么程序仍然能够正常运行,但是我们期望的缓存依赖可能就没有效果了,最终可能会产生性能问题,排查的难度就会大多了。

记得以前做项目时,就遇到过这种情况,当时感到很奇怪,为什么刷新一下就没黄页了,不过后面的错误就很折腾人了,最终也让我总结了这个教训。所以我建议:如果在初始化阶段出现了异常,干脆就别让程序继续运行了,每个请求都直接显示黄页,直到排除故障为止。

如何保证初始化异常一直显示?

当初始化发生异常时,如何保证初始化异常一直显示呢?

方法其实并不难,我们需要修改一下代码:

private static Exception s_initException; void Application_Start(object sender, EventArgs e) { try { AppInitializer.Init(); } catch( Exception ex ) { // 记下初始化的异常。 s_initException = ex; } } protected void Application_BeginRequest(object sender, EventArgs e) { // 如果存在初始化异常,就抛出来。 // 直到开发人员发现这个异常,并已解决了异常为止。 if( s_initException != null ) throw s_initException; }

现在不管有多少个用户来访问,或者第一个访问者刷新浏览器多少次,都会看到同样的异常信息:

如何在应用程序中初始化4

说明:Global.asax的这个问题在IIS7以上版本的集成模式下并不存在。

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新ASP教程学习
热门ASP教程学习
编程开发子分类