Orchard 源码探索(Application_Start)之异步委托调用

Orchard 源码探索(Application_Start)之异步委托调用

2014年5月26日 10:26:31 晴 Orchard 源码探索(Application_Start)之异步委托调用

  • ASP.NET 接收到对应用程序中任何资源的第一个请求时,名为ApplicationManager 的类会创建一个应用程序域。应用程序域为全局变量提供应用程序隔离,并允许单独卸载每个应用程序。
  • 在应用程序域中,将为名为 HostingEnvironment 的类创建一个实例,该实例提供对有关应用程序的信息(如存储该应用程序的文件夹的名称)的访问
  • 为每个请求创建asp.net核心对象。Httpcontext ,HttpRequest, HttpResponse.
  • 将httpapplication对象分配给请求。

    Orchard just begin

 

1
2
3
4
5
protected  void  Application_Start() {
             RegisterRoutes(RouteTable.Routes);
             _starter = new  Starter<IOrchardHost>(HostInitialization, HostBeginRequest, HostEndRequest);
             _starter.OnApplicationStart( this );
         }

其中泛型类Starter的定义如下

 

 

1
public  Starter(Func<HttpApplication, T> initialization, Action<HttpApplication, T> beginRequest, Action<HttpApplication, T> endRequest) {}

 

 

1
2
3
OnApplicationStart-->
     //Run the initialization delegate asynchronously in a queued work item
     public  void  LaunchStartupThread(HttpApplication application)

http://www.codeproject.com/Articles/4201/Proper-Threading-in-Winforms-NET

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/// <summary>
         /// Run the initialization delegate asynchronously in a queued work item
         /// </summary>
         public  void  LaunchStartupThread(HttpApplication application) {
             // Make sure incoming requests are queued
             WarmupHttpModule.SignalWarmupStart();
             ThreadPool.QueueUserWorkItem(
                 state => {
                     try  {
                         var  result = _initialization(application);
                         _initializationResult = result;
                     }
                     catch  (Exception e) {
                         lock  (_synLock) {
                         _error = e;
                             _previousError = null ;
                         }
                     }
                     finally  {
                         // Execute pending requests as the initialization is over
                         WarmupHttpModule.SignalWarmupDone();
                     }
                 });
         }

此函数会使所有扩展模块的初始化委托异步、队列化执行。 先用WarmupHttpModules初始化一个全局静态Action列表,来存储初始化委托,并且无论如何在稍后的异步调用中执行action。

 

总之,Application_Start函数主要作用就是对所有可用扩展的异步队列初始化,其中异步与队列的功能由Orchard.WarmupStarter.Starter类来完成,而可用扩展的初始化加载由IOrchardHost来完成,其中扩展包括:module,core,theme以及子站点的概念。

异步委托

ThreadPool.QueueUserWorkItem(...)

线程池在首次创建 ThreadPool 类的实例时被创建。线程池具有每个可用处理器 25 个线程的默认限制,这可以使用 mscoree.h 文件中定义的 CorSetMaxThreads 来更改。每个线程使用默认的堆栈大小并按照默认的优先级运行。每个进程只能具有一个操作系统线程池。

ThreadPool提供的公共方法都是static方法,因此也不需要生成ThreadPool对象。通过QueueUserWorkItem方法在线程池中添加一个工作项目后,目前没有提供简单的方法取消。你不必建立咨监线程,只需要把相应的函数或方法依托WaitCallback委托传递给ThreadPool.QueueUserWorkItem()方法即可。而线程的创建、管理和运行等等都由系统自动完成,这就是ThreadPool的优点。

*eg: the different between threadpool with normal thread *

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
delegate  void  ShowProgressDelegate ( int  totalMessages, int  messagesSoFar, bool  statusDone );
private  void  button1_Click( object  sender, System.EventArgs e)
{
     ShowProgressDelegate showProgress = new
                                 ShowProgressDelegate(ShowProgress);
     int  imsgs = 100;
     if  ( cbThreadPool.Checked )
     {
         object  obj = new  object [] { this , showProgress, imsgs };
         WorkerClass wc = new  WorkerClass();
         bool  rc = ThreadPool.QueueUserWorkItem( new  WaitCallback
                                             (wc.RunProcess), obj);
         EnableButton( ! rc );
    }
    else
    {
         //another way.. using straight threads
         //WorkerClass wc = new WorkerClass( this, showProgress, imsgs);
         WorkerClass wc = new  WorkerClass( this ,
                 showProgress, new  object [] { imsgs } );
         Thread t = new  Thread( new  ThreadStart(wc.RunProcess));
         //make them a daemon - prevent thread callback issues
         t.IsBackground = true ;
         t.Start();
         EnableButton ( false  );
    }
}

 

可变长数组参数

 

1
public  WorkerClass ( ContainerControl sender, Delegate senderDelegate, ** params  object [] list**);
params 构造函数声明数组 而不知道数组长度 用的 在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。

你可能感兴趣的:(application)