在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前段时间碰到一个问题:为什么在ASP.NET程序中定时器有时候会不工作? 这个问题看起来很奇怪,代码好像也没错,但就是结果与预期不一致。 想到我以前的博客中也零散的说过了一些,所以这篇博客中也把它们列出来了, 不过,对于以前谈过的内容,这里将只会简略地说明。 这个问题是我上个月的博客中提到的问题, 原文链接:http://www.cnblogs.com/fish-li/archive/2013/04/06/3002940.html 在以下情形中访问HttpContext.Current将会返回null 所以,在写类库时,请注意这个问题。 Application_Start的异常与IIS经典模式在IIS6或者II7的经典模式下运行ASP.NET程序时,如果Application_Start事件中抛出了未捕获异常, 那么 这个异常将显示一次。 关于这个问题的更多细节介绍请点击:http://www.cnblogs.com/fish-li/archive/2013/03/24/2979780.html QueryString,Form允许重复的KEY我们经常见到的集合,例如:Hashtable, Dictionary,它们都要求KEY是唯一的,然而, HttpRequest的QueryString,Form集合实例却 允许KEY重复,当遇到KEY重复时,通过索引器访问集合时, 会将KEY对应的所有元素值用逗号拼接起来。 为什么会这样,因为这二个集合的类型是NameValueCollection,类似的,Headers集合也是这样。 由于这个特殊性与我们常见的情形不一致,所以我们需要注意这个差别,当然了,有些时候我们还可以利用这个行为实现一些特殊的需求, 关于这个细节的更多介绍请参考:http://www.cnblogs.com/fish-li/archive/2011/12/06/2278463.html , 在这篇博客中,还介绍了HttpRequest的二个索引器也是值得我们注意的。 ashx的重用问题很多ASP.NET的开发人员都应该创建过ashx文件,例如下面这个: public class Handler1 : IHttpHandler { public bool IsReusable { get { return false; } } 我想不少人会对IsReusable这个属性感到好奇,于是去查一下IHttpHandler的定义,找到这个解释, // 摘要: // 获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。 // // 返回结果: // 如果 System.Web.IHttpHandler 实例可再次使用,则为 true;否则为 false。 bool IsReusable { get; } 看到可以重用,有些对性能关注的人可能会将它修改为返回true,其实改成什么都一样,因为它不起作用。 不起作用的原因在这篇博客中有说明:http://www.cnblogs.com/fish-li/archive/2012/01/29/2331477.html 当前登录用户信息有时获取不到在ASP.NET中,提供了以下方法让我们获取当前用户的信息,例如: if( HttpContext.Current != null ) { // 检查当前用户是否已为一个已登录用户 bool isAuthenticated = HttpContext.Current.Request.IsAuthenticated; // 获取当前请求的用户名 string userName = HttpContext.Current.User.Identity.Name; } 不过,这段代码放在不同的地方,效果却截然不同。 最近就遇到一个问题:有人问我为什么总是取不当前用户的用户名。 当出现这种情况时,我们应该检查代码在哪里被调用的。 凭良心说,这个还真算不上ASP.NET留给我们的坑,只怪一些人对管线事件不了解。 Timer可能会不起作用有时候我们会遇到一些诸如执行定时任务的需求,于是有些人可能会想到用定时器来实现, 在.net framework中,有二个Timer类型可以用于ASP.NET环境中,不过,Timer有可能会不起作用, 具体表现情况也会让你难以描述:不知道在什么时候定时器就停止工作了。 这个问题很奇怪:当你在调试模式下,定时器是一直能正常工作的,但当你把网站部署起来, 运行时间久一些,便会发现定时器没有正常工作。 为什么会这样呢? 正是由于这个原因,建议将长久性的定时任务或者接收Win32回调的程序用Windows Service的程序来实现 Session与复杂数据类型Session有三种工作模式,拿ASPX页面来说,EnableSessionState指令有三个可选值:true, false, ReadOnly EnableSessionState="false",这个容易理解:不使用Session。 EnableSessionState="ReadOnly",从字面上来说,就是Session是只读的。 EnableSessionState="true",表示Session支持可读可写。 进程内Session容易丢失,且不支持多台Web服务器共享数据,因此选择这种保存方法的人不多, 大多数人会选择状态服务或者SQL Server来保存,那么这里就有一个问题需要关注了: 当Session模式是EnableSessionState="true"时,如果你访问了一个复杂对象(不是系统值类型也不是字符串), 不管你有没有修改它,Session的保存操作都会执行。 对于进程外Session,保存操作意味着需要执行序列化,还可以会有网络传输的开销,它们会影响性能。 如果上面的描述不容易理解的话,请看下面的示例代码: string sessionValue = Session["s2"] as string; if( sessionValue == null ) { Session["s2"] = "Fish Li"; sessionValue = Session["s2"] as string; } 当这个页面首次运行时,Session被修改了,因此会有保存的操作发生。但是后面的访问就不会有保存的动作。 再看另一段代码: // TestData是一个自定义类型。 TestData sessionValue = Session["s1"] as TestData; if( sessionValue == null ) { Session["s1"] = new TestData { IntValue = 5, StrValue = "Fish Li" }; sessionValue = Session["s1"] as TestData; } 此时每次执行这段代码时,都会有保存操作发生(只要是EnableSessionState="true")。 我再重申一遍:这个问题只有当EnableSessionState="true",且访问复杂对象(不是系统值类型也不是字符串)才会发生。 对于进程内Session来说,这个问题的影响不大,但是对于进程外Session来说,会对性能产生一些影响, 到底有多大的影响,要根据Session的数据量以及用户的并发度来决定。 列出这个问题只是想告诉大家:如果你确实需要使用Session,请尽量在Session中保存【不可变】的简单数据, 尤其是不要保持Session的默认设置(EnableSessionState="true")。 检验这个问题的方法是:实现一个自定义的SessionStateStoreProviderBase派生类,然后调试观察。 SessionStateItemCollection的二个索引器也会给你一个答案。 DateTime的JSON序列化在SP.NET3.5中,微软为ASP.NET为设计了一个JSON序列化的工具类, System.Web.Script.Serialization.JavaScriptSerializer,这个类的使用很广泛,而且比WCF的那个JSON序列化类的兼容性要好。 不过,这个类有一个问题,在序列化DataTime类型时,它生成的结果会让所有人感觉别扭, 其实序列化的结果表现形式还个小问题,在前端写个转换函数就能解决, 然而,如果你需要 用序列化和反序列化的方法来做对象的持久化,就会遇到问题,例如下面的代码: DateTime dt1 = DateTime.Now; JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(dt1); DateTime dt2 = jss.Deserialize<DateTime>(json); context.Response.Write(dt1 == dt2); 浏览器显示的结果会让人感到很意外,竟然是:False 出现这个原因与JavaScript的时间格式有关,它使用了UTC时间, 不过,这个理由让人感到难以接受,毕竟其它的反序列化都能还原对象,例如二进制序列化和XML都能正确的还原对象。 没办法,这里只能算是个坑了,所以,如果你要做对象的持久化操作,尽量不要选择JSON序列化。 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论