仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 644|回复: 8
打印 上一主题 下一主题

[学习教程] ASP.NET网站制作之抢先手艺:别发急,人懒没成绩

[复制链接]
萌萌妈妈 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:20:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
既然话题已经抄起,我打算今晚发篇博文再引导一下舆论方向,使它再火两天,抛砖引玉,而且赵劼先生一直在跟帖,使.NET阵营的我感到万分难得。在软件开辟中,术语提早指的是尽量久地推延特定的高开支举动的余暇工夫。软件提早过程当中实在也在举行操纵,但意味着任何操纵仅当必要完成某一特定义务时才会产生。就这一点而言,提早是软件开辟中的一种主要形式,能够乐成地使用于包含计划与实行在内的各类情形中。
  比方,极限编程办法中的一种基础编码理论就被复杂地归纳综合为“您不会必要它”,那就是一种明白的提早请求-当且仅当您必要这些功效时,才必要在基础代码中包括它。
  从另外一个角度来看,在实行类的过程当中,当要从难以会见的源中加载数据时,您也大概必要提早。现实上,提早加载形式注释了这类广泛承受的办理计划,即界说一个类成员,但使其坚持为空,直到其他某些客户端代码实践必要其内容时为止。提早加载完整合适在工具干系映照(ORM)工具(照实体框架和NHibernate)情况中利用。ORM工具用于映照面向工具的情况与干系数据库之间的数据布局。比方,在这类情况中,提早加载指的就是仅当某些代码实验读取Customer类上公然的Orders汇合属性时,
框架才干加载Customer的Orders。
  可是,提早加载其实不限于特定的实行计划(如ORM编程)。并且,提早加载指的就是在某些数据实践可用之前不猎取该数据的实例。换言之,提早加载就是要有特别工场逻辑,即跟踪必需要创立的内容,最初在实践哀求该内容时以寂静体例创立该内容。
  在Microsoft.NETFramework中,开辟职员早就在我们的类中手动实行了一切提早举动。在.NETFramework4问世之前,从未有过内置的机制来匡助完成此义务。在.NETFramework4中,我们能够入手下手
利用全新的Lazy<T>类。
  懂得Lazy<T>类
  Lazy<T>是一个特别的工场,您能够用来包装给定T范例的工具。Lazy<T>包装代表一个尚不存在的类实例的及时代办署理。利用Lazy包装的来由有良多,个中最主要的莫过于能够进步功能。提早初始化工具能够制止一切不用要的盘算,从而削减内存损耗。假如加以公道使用,提早初始化工具也能够成为一种加速使用程序启动的壮大工具。以下代码申明了以提早体例初始化工具的办法:
var container = new Lazy<DataContainer>();
  在本例中,DataContainer类暗示的是一个援用了其他工具数组的纯数据容器工具。在方才对Lazy<T>实例挪用完new运算符以后,前往的只是一个及时的Lazy<T>类实例;不管怎样都不会失掉指定范例T的实例。假如您必要向其他类的成员传送一个DataContainer实例,则必需变动这些成员的署名才干利用Lazy<DataContainer>,以下所示:
void ProcessData(Lazy<DataContainer> container);
  什么时候创立DataContainer的实践实例,以便程序能够处置其所需的数据?让我们来看看Lazy<T>类的大众编程接口。该大众接口十分小,由于它只包括两个属性:Value和IsValueCreated。假如存在与Lazy范例联系关系的实例,则属性Value就会前往该实例确当前值。该属性的界说以下:
public T Value 
{ 
 get { ... } 
}
  属性IsValueCreated能够前往一个Boolean值,暗示Lazy范例是不是已过实例化。以下是该属性的源代码中的一段摘录:
public bool IsValueCreated 
{ 
 get 
 { 
  return ((m_boxed != null) && (m_boxed is Boxed<T>)); 
 } 
}
  假如Lazy<T>类包括T范例的实践实例(假如有),则m_boxed成员就是该类的一个外部公有的不不乱成员。因而,IsValueCreated只需反省是不是存在T的及时实例,然后前往一个Boolean谜底。如前文所述,m_boxed成员是公有的而且不不乱(如以下代码段所示):
private volatile object m_boxed;
  在C#中,volatile关头字暗示成员能够被并发运转的线程修正。volatile关头字用于上面如许的成员:这类成员能够在多线程情况中利用,但没法避免多个大概的并发线程同时对其举行会见(本意是出于功能要素思索)。我们稍后再回到Lazy<T>的线程方面下去。今朝,能够一定地说,默许情形下Lazy<T>的大众成员和受回护成员是线程平安的。当有恣意代码初次实验会见Value成员时,就会创立范例T的实践实例。工具创立方面的具体信息取决于各类线程属性,这些属性能够经由过程Lazy<T>机关函数来指定。应当明白的是,线程形式的寄义仅当boxed值实践上已初始化或初次被会见时才很主要。
  默许情形下,范例T的实例是经由过程挪用Activator.CreateInstance举行反射猎取的。以下是一个典范的与Lazy<T>范例举行交互的复杂示例:
var temp = new Lazy<DataContainer>(); 
Console.WriteLine(temp.IsValueCreated); 
Console.WriteLine(temp.Value.SomeValue);
  请注重,在挪用Value之前,其实不必定要对IsValueCreated举行反省。一般情形下,仅当(不管出于何种缘故原由)您必要懂得某个值以后是不是与Lazy范例联系关系时,才必需检察IsValueCreated的值。您无需反省IsValueCreated便可制止产生对Value的空援用非常。以下代码便可包管一般运转:
var temp = new Lazy<DataContainer>(); 
Console.WriteLine(temp.Value.SomeValue);
  Value属性的getter会反省boxed值是不是已存在;假如不存在,则会触发逻辑创立一个包装范例实例,并前往该实例。
  实例化历程
  固然,当该Lazy范例(上例中的DataContainer)的机关函数激发非常时,您的代码会卖力处置该非常。所捕捉非常属于TargetInvocationException范例,该非常是.NET反射没法直接创立某范例实例时收到的典范非常。
  Lazy<T>包装逻辑只能断定是不是已创立范例T的实例,其实不能包管您在会见T上的恣意大众成员时都不会收到空援用非常。以上面的代码段为例:
public class DataContainer 
{ 
 public DataContainer() 
 { 
 } 
 
 public IList<String> SomeValues { get; set; } 
}
  如今假定您实验从客户端程序挪用以下代码:
var temp = new Lazy<DataContainer>(); 
Console.WriteLine(temp.Value.SomeValues.Count);
  在这类情形下,您将收到一个非常,这是由于DataContainer工具的SomeValues属性为空,而非DataContainer自己为空。激发该非常是由于DataContainer的机关函数没有一般初始化其一切成员;该毛病与lazy办法的实行有关。
  Lazy<T>的Value属性为只读属性,即一旦经由初始化,Lazy<T>工具将一直前往统一个范例T实例或统一个值(当T为值范例时)。您没法修正实例,但能够会见该实例大概具有的一切大众属性。
  以下是设置Lazy<T>工具向T范例传送一时参数的办法:
temp = new Lazy<DataContainer>(() => new Orders(10));
  个中一个Lazy<T>机关函数会承受一个托付,您能够经由过程该托付指定为T机关函数发生准确输出数据所需的任何操纵。在初次会见包装的T范例的Value属性之前,不会运转该托付。
  线程平安初始化
  默许情形下,Lazy<T>是线程平安的,即多个线程能够会见一个实例,而且一切线程城市收到统一个
T范例的实例。让我们来看看线程方面的内容,线程仅在初次会见Lazy工具时很主要。
  第一个会见Lazy<T>工具的线程将触发范例T的初始化历程。一切后续取得Value的会见权限的线程城市收到第一个线程(不管甚么线程)天生的呼应。换言之,假如第一个线程在挪用范例T的机关函数时激发了非常,则一切后续挪用(不管甚么线程)城市收到一样的非常。
依照计划,分歧的线程没法从统一个Lazy<T>实例取得分歧的呼应。这是您选择默许的Lazy<T>机关函数时取得的举动。
  可是,Lazy<T>类也能够运转另外一个机关函数:
public Lazy(bool isThreadSafe)
  Boolean参数暗示您是不是必要线程平安。如前文所述,默许值为true,就暗示能够供应上述举动。
  可是,假如您传送的是false,则将只从一个线程(初始化该Lazy范例的线程)会见Value属性。不决义当有多个线程实验会见Value属性时的举动。
  承受Boolean值的Lazy<T>机关函数是一种更罕见署名的特别情形,在这类情形下,您要经由过程LazyThreadSafetyMode列举向Lazy<T>
机关函数传送值。申明了该列举中每一个值的感化。
  LazyThreadSafetyMode列举
值申明
NoneLazy<T>实例不是线程平安的,而且不决义当从多个线程会见该实例时的举动。
PublicationOnly同意多个线程同时实验初始化Lazy范例。第一个完成的线程是得胜者,一切其他线程天生的了局都将被抛弃。
ExecutionAndPublication为了确保只要一个线程可以以线程平安的体例初始化Lazy<T>实例而利用了锁。

  您可使用以下任一机关函数来设置PublicationOnly形式:
public Lazy(LazyThreadSafetyMode mode) 
public Lazy<T>(Func<T>, LazyThreadSafetyMode mode)
  中除PublicationOnly之外的值都是在利用承受Boolean值的机关函数时隐式设置的:
public Lazy(bool isThreadSafe)
  在该机关函数中,假如参数isThreadSafe为false,则选定的线程形式为None。假如参数isThreadSafe设置为true,则线程形式设置为ExecutionAndPublication。ExecutionAndPublication也是您选择默许机关函数时的事情形式。
  利用ExecutionAndPublication时能够包管完整线程平安,利用None时缺少线程平安,而利用PublicationOnly形式则介于两者之间。PublicationOnly同意多个并发线程实验创立范例T实例,但只同意一个线程是得胜者。得胜者创立的T实例随后会在一切其他线程(不管每一个线程盘算的实比方何)之间共享。
  就初始化过程当中大概激发非常方面,None和ExecutionAndPublication之间有一个很风趣的区分。当设置为PublicationOnly且初始化过程当中发生的非常未写进缓存时,假如T实例不成用,则实验读取Value的每一个后续线程都无机会从头初始化该实例。PublicationOnly和None之间的另外一个区分是,当T的机关函数实验递回会见Value时,PublicationOnly形式中不会激发任何非常。当Lazy<T>类以None或ExecutionAndPublication形式事情时,该情形会激发InvalidOperation非常。
  保持线程平安能够取得原本的功能上风,但要注重避免呈现使人厌恶的Bug和争用情形。因而,倡议您仅当功能极其关头时才利用LazyThreadSafetyMode.None选项。
  利用LazyThreadSafetyMode.None时,您必要卖力确保毫不会产生从多个线程对Lazy<T>实例举行初始化的情形。不然,大概会发生不成意料的了局。假如初始化过程当中激发非常,则关于该线程,对Value的一切后续会见城市缓存和激发不异的非常。
  ThreadLocal初始化
  依照计划,Lazy<T>克制分歧的线程办理其各自的范例T实例。可是,假如您但愿同意该举动,
您必需选择其他类(ThreadLocal<T>范例)。以下是该类的利用办法:
var counter = new ThreadLocal<Int32>(() => 1);
  机关函数会承受一个托付,并利用该托付来初始化thread-local变量。每一个线程城市保存本人的数据,其他线程完整没法会见该数据。与Lazy<T>分歧,ThreadLocal<T>上的Value属性是可读写的。因而,每一个会见与下一个会见之间是自力的,大概发生包含激发(或不激发)非常在内的分歧了局。假如您未经由过程ThreadLocal<T>机关函数供应操纵托付,则嵌进的工具将利用该范例的默许值null(当T为一个类时)举行初始化。
  完成Lazy属性
  年夜多半情形下,您要利用Lazy<T>作为您本人的类中的属性,但究竟是哪些类中要利用它呢?ORM工具自己供应了提早加载功效,因而假如您利用的是这些工具,在数据会见层地点的使用程序片断中极可能找不到大概承载lazy属性的候选类。假如您利用的不是ORM工具,则数据会见层一定十分合适lazy属性。
  能够在个中利用依附干系注进的使用程序片断也大概十分合适提早。在.NETFramework4中,托管可扩大性框架(MEF)只利用Lazy<T>来完成控件的可扩大性和反转。即便您不是间接利用MEF,依附干系的办理也十分合适lazy属性。
  在类中完成lazy属性其实不坚苦,如所示。
  Lazy属性示例
public class Customer 
{ 
  private readonly Lazy<IList<Order>> orders; 
 
  public Customer(String id) 
  { 
   orders = new Lazy<IList<Order>>( () => 
   { 
     return new List<Order>(); 
   } 
   ); 
  } 
 
  public IList<Order> Orders 
  { 
   get 
   { 
     // Orders is created on first access 
     return orders.Value; 
   } 
  } 
}
  增补申明
  总而言之,提早加载是一个笼统的观点,指的是仅认真正必要数据时才加载数据。在.NETFramework4问世之前,开辟职员必要本人开辟提早初始化逻辑。Lazy<T>类扩大了.NETFramework编程工具包,可以让您在当且仅当严厉必要高开支工具时,才在刚好入手下手利用这些工具之前对这些工具举行实例化,从而制止华侈盘算资本。
有专家说:java不是跨平台,java就是平台,这很好的定义了java的特点。有了java,你只需要等待java平台在新平台上移植。这还不错吧!只是,java不是一个平台,而是多个平台。你需要在这个java平台移植到另一个java平台。
小女巫 该用户已被删除
沙发
发表于 2015-1-19 09:06:49 | 只看该作者
asp.net空间的支持有:ASP.NET1.1/虚拟目录/MicrosoftFrontPage2000扩展/CDONTS,同时他的网站上也提供了Asp.net的使用详解和程序源代码,相信对使用ASP.NET编程的程序员来说会非常有用哦!
admin 该用户已被删除
板凳
发表于 2015-1-24 16:07:35 | 只看该作者
ASP.net的服务器,要求安装一个.net环境,当然我这里指的是windows系统,顺便点一下,.net只能放在windows环境里来运行。Asp.net1.1的就装Framework1.1,Asp.net2.0的就装Framework2.0。
乐观 该用户已被删除
地板
发表于 2015-2-2 10:20:34 | 只看该作者
同时也感谢博客园给我们这个平台,也感谢博客园的编辑们做成专题引来这么多高人指点。
再见西城 该用户已被删除
5#
发表于 2015-2-7 18:01:37 | 只看该作者
最强的技术支持WebService,而且有.NET的所有library做后盾。而且ASP.NET在.NET3.5中还有微软专门为AJAX开发的功能--ASP.NETAJAX。
简单生活 该用户已被删除
6#
发表于 2015-2-22 20:17:09 | 只看该作者
业务逻辑代码都不必做任何改动;继承性和多态性使得代码的可重用性大大提高,你可以通过继承已有的对象最大限度保护你以前的投资。并且C#和C++、Java一样提供了完善的调试/纠错体系。
再现理想 该用户已被删除
7#
发表于 2015-3-7 02:31:20 | 只看该作者
PHP的源代码完全公开,在OpenSource意识抬头的今天,它更是这方面的中流砥柱。不断地有新的函数库加入,以及不停地更新,使得PHP无论在UNIX或是Win32的平台上都可以有更多新的功能。它提供丰富的函数,使得在程式设计方面有着更好的资源。目前PHP的最新版本为4.1.1,它可以在Win32以及UNIX/Linux等几乎所有的平台上良好工作。PHP在4.0版后使用了全新的Zend引擎,其在最佳化之后的效率,比较传统CGI或者ASP等技术有了更好的表现。
柔情似水 该用户已被删除
8#
发表于 2015-3-14 10:28:49 | 只看该作者
逐步缩小出错代码段的范围,最终确定错误代码的位置。
灵魂腐蚀 该用户已被删除
9#
发表于 2015-3-21 03:36:49 | 只看该作者
由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-24 01:33

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表