成都网站建设
|
域名注册
|
虚拟主机
|
网站制作
|
网站案例
|
网站优化
|
网站推广
|
企业邮局
|
服务器租用
|
广告设计
首页
服务器租用
企业邮箱
虚拟主机
网站程序
营销推广
网站建设
域名注册
前端开发
网站备案
网站策划
|
网站建设
|
网站案例
|
虚拟主机
|
网站推广
|
云服务器
|
成都网站制作公司
|
php空间
|
独立IP空间
|
jsp虚拟主机
网站程序
java教程
asp程序
asp.net程序
vb编程
php程序
C#程序
服务器租用
web服务器
FTP服务器
服务器托管
服务器租用
vps主机服务器
企业邮箱
企业邮箱优势
企业邮箱设置
邮箱收发问题
邮箱功能讲解
邮箱其他问题
虚拟主机
主机购买
数据库
主机管理
FTP上传
主机续费升级
营销推广
seo优化
网站推广
搜索引擎
免费资源
网站建设
网站方案
网站改版
网页设计
网站维护
网站策划
域名注册
域名转入\转出
英文域名
通用网址
中文域名
域名解析
前端开发
html
jQuery
JavaScript教程
css
div+css
网站备案
备案流程指南
备案资料下载
备案常见问题
各省备案要求
移动互联网
wap手机网站
app应用开发
微网站
当前位置:
创新互联
>>
常见问题
>>
网站程序
>>
asp.net程序
>>
从.NET类库代码来看ASP.NET运行时之二
从.NET类库代码来看ASP.NET运行时之二
作者:创新互联 文章来源:网站程序部 点击数:
更新时间:2013-08-26
Asp.net运行时,我们等待已久的纯托管代码环境
好,经过上面长久的铺垫,
创新互联网站建设
小编要带大家进入了托管代码的领域。经过前面的内容,我们知道,在托管代码中首先被执行的是一个ISAPIRuntime对象的ProcessRequest方法,那么下面我们就来看一看这个方法主要做了些什么:
1/**//*ISAPIRuntime的方法,处理请求的入口。*/
2public int ProcessRequest(IntPtr ecb, int iWRType)
3{
4 try
5 {
6 /**//*这里ecb被作为参数传入,返回一个HttpWorkerRequest类型的对象,作为对一个请求的
数据库
的封装。但HttpWorkerRequest
7 *只是一个抽象基类,CreateWorkerRequest作为一个工厂方法,返回的实际类型是ISAPIWorkerRequestInProc,
8 *ISAPIWorkerRequestInProcForIIS6或ISAPIWorkerRequestOutOfProc。这些类型里面提供的方法,其实大多
9 *围绕着如何从ecb中去
获取数据
,所以都包含了很多对System.Web.UnsafeNativeMethods类型中静态方法的调用。
10 **/
11 HttpWorkerRequest wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, iWRType);
12 string appPathTranslated = wr.GetAppPathTranslated();
13 string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
14 if ((appDomainAppPathInternal == null) || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
15 {
16 /**//*从这里开始,对请求的处理流程就交给了HttpRuntime。需要注意的是,ISAPI是多线程的,而且对ProcessRequest的调用是异步的,
17 *这就要求HttpRuntime.ProcessRequest方法是线程安全的。看一看HttpRuntime.ProcessRequestNoDemand里的代码大家就清楚,
18 *所有的请求会被排成一个队列,顺次执行,保证了并发安全。
19 *最终,HttpRuntime.ProcessRequestInternal方法会被调用,我们接下来就去看看那个方法。
20 **/
21 HttpRuntime.ProcessRequestNoDemand(wr);
22 return 0;
23 }
24 HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[] { appDomainAppPathInternal, appPathTranslated }));
25 }
26 catch (Exception exception)
27 {
28 Misc.ReportUnhandledException(exception, new string[] { SR.GetString("Failed_to_process_request") });
29 throw;
30 }
31 return 1;
32}
上面的代码段最主要的作用就是调用了HttpRumtime.ProcessRequestInternal方法,下面我们就一起来看看这个方法的实现:
1/**//*在HttpRuntime.ProcessRequestInternal()方法里,有如下几个重要的对象被创建出来:
2 *(1)HttpContext(包括其中的HttpRequest,HttpResponse)
3 *(2)HttpApplication
4 *同时,会执行HttpApplication对象的ProcessRequest方法,
5 */
6private void ProcessRequestInternal(HttpWorkerRequest wr)
7{
8 /**//*HttpContext对象在这里被创建。HttpWorkerRequest做为构造参数,而HttpWorkerRequest本身
9 *又围绕着对ecb的处理建立了一群高层的方法,它的实例会被HttpContext传给HttpRequest和HttpResponese
10 *做为他们的构造参数。所以,这里也能更清楚地看出HttpWorkerRequest作为ecb的托管环境封装器的实质。
11 *另外,这里也能清楚地反映出,每一个请求都有一个自己的HttpContext对象(而每一个Context对象都管理着
12 *一个HttpSession对象--参见HttpContext的Session属性,这也就保证了每个访问者有自己的session对象。),你可以
13 *使用HttpContext.Current来访问到这个对象。
14 */
15 HttpContext extraData = new HttpContext(wr, false);
16 wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, extraData);
17 Interlocked.Increment(ref this._activeRequestCount);
18 HostingEnvironment.IncrementBusyCount();
19 try
20 {
21 try
22 {
23 this.EnsureFirstRequestInit(extraData);
24 }
25 catch
26 {
27 if (!extraData.Request.IsDebuggingRequest)
28 {
29 throw;
30 }
31 }
32 extraData.Response.InitResponseWriter();
33 /**//*用应用程序工厂返回一个HttpApplication对象。
34 *和线程池对线程的管理相似,HttpApplicationFactory中以stack维护了一个HttpApplication的列表(参见HttpApplicationFactory
35 *的_freeList变量)。在这句方法调用的最后,实际是调用了 _theApplicationFactory.GetNormalApplicationInstance(context),
36 *里面就是从_freeList的栈顶pop出一个已经构造的HttpApplication实例。
37 *所以,对于每一个请求,由HttpContext作为上下文,由一个HttpApplication对象来控制整个应用处理的pipeline,整个
38 *处理过程是在由工作进程管理的线程池中的某个线程内完成的。
39 *另外,在一个应用程序域内,由于可以同时处理多个请求,所以就有多个HttpApplication实例和多个活动线程(您可以使用windbg的sos
40 *扩展来观察它们之间的关系,本文就不继续深入了)。
41 *还有,对所有HttpModules的加载就是发生在HttpApplication对象的创建过程之中(包括系统已经提供的Authentication等模块儿和我们
42 *的自定义模块)。我们可以在Web.config里声明自己的自定义模块。这些模块的作用就是在整个HttpApplication处理管线的相关事件点上,
43 *挂上自己的处理。注意一下IHttpModule接口的Init()方法的声明,这个方法的传入参数就是要被创建的HttpApplication对象,所以,如果
44 *你自己的模块想在缓存读取上加入一些自定义操作,你只需进行如下处理即可:
45 public class YourCustomModule : IHttpModule
46 {
47 public void Init(HttpApplication application)
48 {
49 application.ResolveRequestCache += new EventHandler(this.YourCustomResolveRequestCache);
50 }
51 }
52 *另外,通过对HttpApplicationFactory.GetApplicationInstance方法内部实现方式的阅读,你会发现在每一个HttpApplication对象被创建
53 *之后,会立刻调用这个对象的InitInternal方法,而这个方法里面做了很多重要的初始化操作,内容较多,我们将在下文中单独介绍。
54 *
55 */
56 IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(extraData);
57 if (applicationInstance == null)
58 {
59 throw new HttpException(SR.GetString("Unable_create_app_object"));
60 }
61 if (EtwTrace.IsTraceEnabled(5, 1))
62 {
63 EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, extraData.WorkerRequest, applicationInstance.GetType().FullName, "Start");
64 }
65 /**//*看一下System.Web.HttpApplication的类型声明
66 *public class HttpApplication : IHttpAsyncHandler, IHttpHandler, IComponent, IDisposable
67 *你会发现它同时实现了同步和异步的IHandler,所以在默认情况下,Asp.net对请求的处理是异步的。
68 */
69 if (applicationInstance is IHttpAsyncHandler)
70 {
71 IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;
72 alt="" src="/imagelist/2007/236/b2dc295wopin.gif" align=top> extraData.AsyncAppHandler = handler2;
73 /**//*BeginProcessRequest会调用HttpApplication的ResumeSteps()方法,在ResumeSteps()中完成了整个应用程序周期的所有操作,
74 *包括对所有事件的触发、执行,对Handler的调用等。后文会有专门的小节进行介绍。*/
75 handler2.BeginProcessRequest(extraData, this._handlerCompletionCallback, extraData);
76 }
77 else
78 {
79 applicationInstance.ProcessRequest(extraData);
80 this.FinishRequest(extraData.WorkerRequest, extraData, null);
81 }
82 }
83 catch (Exception exception)
84 {
85 extraData.Response.InitResponseWriter();
86 this.FinishRequest(wr, extraData, exception);
87 }
88}
从上面的代码可以看出,HttpApplication对象是经由HttpApplicationFactory.GetApplicationInstance(并最终调用HttpRuntime.CreateNonPublicInstance)创建的。HttpApplicationFactory对象会先解译目录中的Global.asax文件,接着加载虚拟目录内的Application Assembly(Global.dll),而后合并两者创建出一个Ghost Application Class,最后编译此Class后取得对象实例后返回至untime对象,这个对象实例就是HttpApplication对象。解译与编译.asax文件的动作只发生于此虚拟目录第一次处理用户
浅析.net策略模式
:上一篇
asp.net与asp的功能上的区别?
:下一篇
asp.net程序相关文章
浅析.net策略模式
.NET中方法的注意事项总结
ASP.NET生成两个日期范围内...
.NET中的属性用法分析
ASP站点如何设置防盗链
ASP.NET 2.0 中的数据...
关于ASP.NET调用JavaS...
用.net 处理xmlHttp发...
专注网站建设、网页设计、网站制作、企业网站建设——创新互联
移动互联网
|
网站备案
|
前端开发
|
域名注册
|
网站建设
|
营销推广
|
网站程序
|
虚拟主机
|
企业邮箱
|
服务器租用
|
热门搜索
服务电话:028-86922220 13518219792 公司地址:成都市太升南路288号锦天国际A幢10楼2号
企业邮箱:
service@cdxwcx.com
版权所有:成都创新互联科技有限公司 蜀ICP备09010846号
成都网站建设