ASP.NET开发经验收集
一:页面中Page_Load事件 和 Page.IsPostBack执行两次的原因.
原因一:
当<%@Page....中没有AutoEventWireup定义时会导致Page_Load执行两次,如果有定义,且值为true时,在IsPostBack中动态绑定控件等情况也会导致页面Load事件发生两次..因此,个人推荐不要忽视AutoEventWireup,且建议设置其值为 false;
原因二:
当页面中有<img src="">时,也可能会导致Page_Load执行两次,解决方法:我也唔知.
二:OnInit与OnLoad
个人理解:如果页面禁用了视图或者逻辑过程中没有用到视图或者没有必要回发数据的话,可以直接重写OnLoad方法,而不用再写OnInit方法,因为OnInit()之后还有进行一些视图方法的操作及回发数据的处理.因此直接OnLoad效率会高一些.
三:远程服务器返回500错误
过程中需要从远程服务器下载文件到本地.可一直报远程服务器返回500错误.检查来检查去,结果错误发生在本地:
原因:页面以ANSI编码保存,而本地完全路径中有中文字符,导致路径不能被程序有效识别.
解决方法:将页面编码更换成utf-8即可.VS系列中可通过高级保存选项更改.
四:Response.End,Response.Redirect等导致"正在中止线程"的问题
如果是Response.End(),可用HttpContext.Current.ApplicationInstance.CompleteRequest()来代替(据个人测试,貌似使用这句后,后边不能再有程序执行,否则仍然会继续执行下去?)
对于Response.Redirect()可用其重载方法:Response.Redirect(string,bool)
当然,Server.Execute(),Server.Transfer()情况也类似.
附上ASP.NET页面的生存周期(看明白了就知道为何有时只需要OnLoad,而不需要OnInit了)
____
一:初始化Init:初始化对象--Init事件(OnInit方法)
二:加载视图状态:LoadViewState方法
三:处理回发数据:LoadPostData方法---实际上这一步只是加载,并没有做其它的处理.
---实现该方法的控件要继承自IPostBackDataHandler接口,该接口有LoadPostData和RaisePostBackDataChangedEvent两个方法
四:加载Load:---Load事件(OnLoad方法)---该过程中所有对象都已经被实例化了..
五:发送回发更改通知:RaisePostBackDataChangedEvent方法
六:处理回发事件:IPostBackEventHandler接口的RaisePostBackEvent方法.
七:预呈现:OnPreRender方法(PreRender事件)
八:保存视图状态:SaveViewState方法
九:呈现:Render方法(--不再有对应事件)
十:处置,回收资源:Dispose方法
十一:卸载:UnLoad事件(OnUnLoad方法)..
---------Page是从Control继承的,因此它也是一种特殊的控件!
五:IHttpModule的Init()只执行一次:
IHtttpModule.Init()方法是在Application启动时进行一些初始化操作,因此,该方法只需要而且也只会执行一次.
因此,在该方法里调用的方法也只会执行一次(我们可以在其中实现Timer,FileSystemWatcher等的操作).
当然,其中的Application相关事件是在这一步注册.
----
需要注意的是,有些情况下,Init()也会多次执行,比如使用框架时就会执行不止一次...
http://www.cnblogs.com/redfire0922/archive/2007/03/15/675549.html
这里有位朋友就碰到类似问题.
六:内存回收,Dispose,Close,Finalie(C#中的析构函数)
.NET中的资源分托管和非托管,所谓的托管是指CLR(通用语言运行时)中进行管理的资源,它可以由CLR自动进行内存回收.
也就是大家熟知的GC(垃圾回收机制).
而对于 非托管资源,比如数据库连接,COM连接等,那么需要手动清理回收资源.
清理非托管资源,我们可以用析构函数来执行,虽然它的执行时机不确定,但终究会被执行.
当然还有Dispose()和Close()方法,两者的区别在于,Close()后还要以用Open()打开,而Dispose()则是彻底销毁.
---
使用析构函数时,需要GC.Collect()才会执行到(GC,Collect()在自动回收机制中会自动执行,也可以显式调用它)
而Dispose()需要显式地调用,或者使用using()
,但是,需要注意:在用析构函数时,至少分两步走:调用函数,回收内存.
那么,在用using()或*.Dispose()后,GC还会再去执行析构函数.
因此,在Dispose()里,加上GC.SupressFinalize(this)来防止再次调用析构函数.
总结:
Dispose()和Close()需要显示调用,Dispose()可以通过using()调用.析构函数无法显式调用.
Dispose()和析构函数是销毁对象,而Close()是关闭,可以通过Open()再开.
析构函数调用时机不确定,而Dispose()在显式或Using()时执行,Close()在显式时执行.
三者都是用来销毁非托管对象.
一段经典的C#-Dispose:
原因一:
当<%@Page....中没有AutoEventWireup定义时会导致Page_Load执行两次,如果有定义,且值为true时,在IsPostBack中动态绑定控件等情况也会导致页面Load事件发生两次..因此,个人推荐不要忽视AutoEventWireup,且建议设置其值为 false;
原因二:
当页面中有<img src="">时,也可能会导致Page_Load执行两次,解决方法:我也唔知.
二:OnInit与OnLoad
个人理解:如果页面禁用了视图或者逻辑过程中没有用到视图或者没有必要回发数据的话,可以直接重写OnLoad方法,而不用再写OnInit方法,因为OnInit()之后还有进行一些视图方法的操作及回发数据的处理.因此直接OnLoad效率会高一些.
三:远程服务器返回500错误
过程中需要从远程服务器下载文件到本地.可一直报远程服务器返回500错误.检查来检查去,结果错误发生在本地:
原因:页面以ANSI编码保存,而本地完全路径中有中文字符,导致路径不能被程序有效识别.
解决方法:将页面编码更换成utf-8即可.VS系列中可通过高级保存选项更改.
四:Response.End,Response.Redirect等导致"正在中止线程"的问题
如果是Response.End(),可用HttpContext.Current.ApplicationInstance.CompleteRequest()来代替(据个人测试,貌似使用这句后,后边不能再有程序执行,否则仍然会继续执行下去?)
对于Response.Redirect()可用其重载方法:Response.Redirect(string,bool)
当然,Server.Execute(),Server.Transfer()情况也类似.
附上ASP.NET页面的生存周期(看明白了就知道为何有时只需要OnLoad,而不需要OnInit了)
____
一:初始化Init:初始化对象--Init事件(OnInit方法)
二:加载视图状态:LoadViewState方法
三:处理回发数据:LoadPostData方法---实际上这一步只是加载,并没有做其它的处理.
---实现该方法的控件要继承自IPostBackDataHandler接口,该接口有LoadPostData和RaisePostBackDataChangedEvent两个方法
四:加载Load:---Load事件(OnLoad方法)---该过程中所有对象都已经被实例化了..
五:发送回发更改通知:RaisePostBackDataChangedEvent方法
六:处理回发事件:IPostBackEventHandler接口的RaisePostBackEvent方法.
七:预呈现:OnPreRender方法(PreRender事件)
八:保存视图状态:SaveViewState方法
九:呈现:Render方法(--不再有对应事件)
十:处置,回收资源:Dispose方法
十一:卸载:UnLoad事件(OnUnLoad方法)..
---------Page是从Control继承的,因此它也是一种特殊的控件!
五:IHttpModule的Init()只执行一次:
IHtttpModule.Init()方法是在Application启动时进行一些初始化操作,因此,该方法只需要而且也只会执行一次.
因此,在该方法里调用的方法也只会执行一次(我们可以在其中实现Timer,FileSystemWatcher等的操作).
当然,其中的Application相关事件是在这一步注册.
----
需要注意的是,有些情况下,Init()也会多次执行,比如使用框架时就会执行不止一次...
http://www.cnblogs.com/redfire0922/archive/2007/03/15/675549.html
这里有位朋友就碰到类似问题.
六:内存回收,Dispose,Close,Finalie(C#中的析构函数)
.NET中的资源分托管和非托管,所谓的托管是指CLR(通用语言运行时)中进行管理的资源,它可以由CLR自动进行内存回收.
也就是大家熟知的GC(垃圾回收机制).
而对于 非托管资源,比如数据库连接,COM连接等,那么需要手动清理回收资源.
清理非托管资源,我们可以用析构函数来执行,虽然它的执行时机不确定,但终究会被执行.
当然还有Dispose()和Close()方法,两者的区别在于,Close()后还要以用Open()打开,而Dispose()则是彻底销毁.
---
使用析构函数时,需要GC.Collect()才会执行到(GC,Collect()在自动回收机制中会自动执行,也可以显式调用它)
而Dispose()需要显式地调用,或者使用using()
,但是,需要注意:在用析构函数时,至少分两步走:调用函数,回收内存.
那么,在用using()或*.Dispose()后,GC还会再去执行析构函数.
因此,在Dispose()里,加上GC.SupressFinalize(this)来防止再次调用析构函数.
总结:
Dispose()和Close()需要显示调用,Dispose()可以通过using()调用.析构函数无法显式调用.
Dispose()和析构函数是销毁对象,而Close()是关闭,可以通过Open()再开.
析构函数调用时机不确定,而Dispose()在显式或Using()时执行,Close()在显式时执行.
三者都是用来销毁非托管对象.
一段经典的C#-Dispose:
private bool _isDisposed=false;
~MyTest()
{
//this.Close();
Dispose(false);
}
/**//// <summary>
/// 内存释放,需要此类实例显式调用,如sql.Dispose();或Using()
/// </summary>
public void Dispose()
{
//IDisposable dispose = this as IDisposable;
//if(dispose!=null)
//{
// dispose.Dispose();
//}
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!_isDisposed)
{
if(disposing)
{
//托管资源的释放
}
//非托管资源的释放
_isDisposed = true;
}
}
~MyTest()
{
//this.Close();
Dispose(false);
}
/**//// <summary>
/// 内存释放,需要此类实例显式调用,如sql.Dispose();或Using()
/// </summary>
public void Dispose()
{
//IDisposable dispose = this as IDisposable;
//if(dispose!=null)
//{
// dispose.Dispose();
//}
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!_isDisposed)
{
if(disposing)
{
//托管资源的释放
}
//非托管资源的释放
_isDisposed = true;
}
}

浙公网安备 33010602011771号