周末下了点狠心,决定把项目升级到2.0平台,因为VS2003和2005可以并存,所以问题还是比较容易处理的,装上Pro版的2005,打开原来的项目,自动出现升级向导。项目里包含7个子项目,所有的逻辑和显示都是在后台项目里实现的,前台的Web项目里每个文件里都只是实现了一个对后台方法的调用,而且后台也没有用到任何高级的语法,因此升级非常平滑。
总结了一下,Web项目里的项目文件被删除了。原来两个不相干的ASPX文件也被考虑进编译过程了。编译了一下,上传到服务器上,报错。后来发现新编译的项目没有Web项目的Dll了,而服务器的目录上还留着。结果造成内部引用的混乱。删除那个老的Web项目的Dll,OK了。
然后打算试一下发布模式,用VS2005的生成菜单项目里的发布网站功能,设置发布到的目录,选项设成不允许更新,它居然把Web目录下所有的东西复制了一遍出来,所以编译过程很慢。编译完成以后在bin目录下生成了一堆东西,我以为把这些东西拷到服务器上就可以不用干净编译了。结果发现第一次访问页面的时候,还是会出现csc进程。整个网站切换过来以后,还是同样出现了一堆的csc进程,不过编译过程比原来快了一点。
另外出现的一个比较严重的问题,程序似乎过一会就会自动重启一下,导致再编译一次,而且后来发现服务器上出现了一个错误窗口,说是w3wp.exe进程出现错误,是否要进行调试。选择取消以后,w3wp.exe就自动重启了,于是又开始了新一轮的重新编译。这个过程出现了三次,吓的我赶紧切换回去1.1的版本。到事件查看器里看了一下,里面一堆的未处理异常,基本上都是值为空的错误。奇怪了,在1.1的时候没有出现过问题啊,而且代码没有进行改变。
后来查到一篇文章(中文的似乎还没有人提到过),,在2.0里面对未处理的异常的处理方式跟1.1有很大的不同,1.1会忽略它,除非影响页面生成。而2.0会导致进程报错,直接影响整个网站运行。听上去是个很严重的问题,但是这样似乎更合理,否则程序员会一直忽略掉这个错误。然而因为这个问题,网站无法切换也是个很严重的问题,因此,还是需要一个平滑过度的方法。上文提到了这个方法,就是自己写一个HttpModule,处理所有的未处理异常,并且可以把异常信息记入系统事件,有利于程序员进行处理。并且上文也提供了这个HttpModule的源码和二进制文件下载,还包含Demo的WebApp。
今天终于弄懂了2.0的预部署发布的编译方式,用VS的发布网站的方式是不对的,一定要用aspnet_compiler.exe来手动编译,而且它的编译过程是针对网站的实际设置的。也就是说,必须把Web项目的内容上传到网站上去,在IIS里面设好网站的路径,然后使用aspnet_compile进行编译,可以进行本地编译,这个过程实际上它是把生成的dll放到C:\Windows\Microsoft.Net里面的缓存目录里的,也就是跟用户实际访问页面的时候csc.exe生成的是完全一致的。经过这一部,用户两次访问的时候就不会有任何编译动作发生了。
好累。顺便想到一个无缝切换的方式,分别保留两个网站,指向两个不同的目录,其中一个是没有主机头的,另一个是有主机头的,用来更新的。更新这个有主机头的网站以后,使用aspnet_compiler编译一下,然后切换两个网站的主机头,这样新访问的用户就会被导向这个新编译过的网站,而用户不会感觉到任何延迟。下次再更新另外一个站点就可以了。