Run Tasks in an ASP.NET Application Domain

來源:互聯網
上載者:User

 

Keywords: Task implement, ASP.NET 2.0 Provider Model

Web應用中有很多耗時的操作比如發送email、產生報表、處理上傳圖片等等,這些操作是不適合放到頁面中的。比如回複一個文章後email通知所有訂閱了該文章更新的使用者,如果在回複操作中處理,那麼使用者回複文章時大部分的時間就會浪費在發送email上了。在CommunityServer裡,類似的耗時的操作都被獨立出來,作為獨立的任務運行於服務端同一程式域中的一個或多個線程中。本文通過email notification的實現,來具體瞭解一下這種實現模式。涉及的知識點包括:.NET configuration API, Provider Model,  ASP.NET 多線程, 抽象原廠模式等。

描述:CS Email Notifcation 包括兩部分產生email和發送email。產生email時,針對每個發送地址產生了一個具體的.NET Mail Mesage對象,序列化後存入資料庫。發送時還原序列化每個Mail Message對象,調用.NET SMTP API發送。發送email可以作為服務獨立出來,而產生email是和具體的業務相關的,不能作為獨立的服務。但這也是個耗時的操作,涉及到序列化,有時也會有大量email的產生。CS採用非同步事件調用,模仿Http Module,定義全域事件,以plug-in的方式載入module,在module中hook全域事件,在事件中處理具體的操作,如產生email。通過事件,使主程式之外的操作非同步進行。以Provider Model的方式來hook事件,增強了程式的可擴充性,實現了隨插即用。

代碼:

部分代碼下載

先看一下設定檔,CS中並沒有使用.net 設定檔(即web.config檔案)和標準API,本文將其修改為標準的,並採用ASP.NET 2.0中標準的Provider Model。

 

  <configSections>
    <section name="poConfiguration" type="PO.Component.Configuration.POConfigurationSection, PO.Component"/>
  </configSections>
  <poConfiguration>
    <modules>
      <add name="EmailNotificationModule" type="PO.Component.Module.EmailNotificationModule, PO.Component" />
    </modules>
    <providers>
      <add name="CommonDataProvider" type="PO.Component.Provider.SqlCommonDataProvider, PO.Component" connectionStringName="ShippingWisePortalConnectionString" />
      <add name="EmailTemplateProvider" type="PO.Component.Provider.XmlEmailTemplateProvider, PO.Component" />
      <add name="NotificationProvider" type="PO.Component.Provider.EmailNotificationProvider, PO.Component" />
    </providers>
    <tasks>
      <modules>
      </modules>
      <threads>
        <thread minutes="1">
          <add name="Emails" type="PO.Component.Task.EmailJob, PO.Component" enabled="true" enableShutDown="false" failureInterval="1" numberOfTries="10" />
        </thread>
      </threads>
    </tasks>
  </poConfiguration>

設定檔的操作:

整個自訂節poConifguration

namespace PO.Component.Configuration
{
    public class POConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("modules")]
        public ProviderSettingsCollection Modules
        {
            get { return (ProviderSettingsCollection)base["modules"]; }
        }
        [ConfigurationProperty("providers")]
        public ProviderSettingsCollection Providers
        {
            get { return (ProviderSettingsCollection)base["providers"]; }
        }
        [ConfigurationProperty("tasks")]
        public TasksElement Tasks
        {
            get { return (TasksElement)base["tasks"]; }
        }
  
    }
}

tasks子節

namespace PO.Component.Configuration
{
    public sealed class TasksElement : ConfigurationElement
    {
        [ConfigurationProperty("modules")]
        public ProviderSettingsCollection Modules
        {
            get { return (ProviderSettingsCollection)base["modules"]; }
        }
        [ConfigurationProperty("threads")]
        public ThreadSettingsCollection Threads
        {
            get { return (ThreadSettingsCollection)base["threads"]; }
        }
    }
}

tasks子節中的threads節

namespace PO.Component.Configuration
{
    [ConfigurationCollection(typeof(TaskSettingsCollection))]
    public sealed class ThreadSettingsCollection : ConfigurationElementCollection
    {
        public TaskSettingsCollection this[int index]
        {
            get
            {
                return (TaskSettingsCollection)base.BaseGet(index);
            }
            set
            {
                if (base.BaseGet(index) != null)
                {
                    base.BaseRemoveAt(index);
                }
                this.BaseAdd(index, value);
            }
        }

        public new TaskSettingsCollection this[string key]
        {
            get
            {
                return (TaskSettingsCollection)base.BaseGet(key);
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new TaskSettingsCollection();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return string.Empty;
        }
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            {
                return ConfigurationElementCollectionType.BasicMap;
            }
        }
        protected override string ElementName
        {
            get
            {
                return "thread";
            }
        }
    }
}

threads節中的thread節

namespace PO.Component.Configuration
{
    [ConfigurationCollection(typeof(ProviderSettings))]
    public sealed class TaskSettingsCollection : ConfigurationElementCollection
    {
        [ConfigurationProperty("minutes", IsRequired = false, DefaultValue = 15)]
        public int Minutes
        {
            get { return (int)base["minutes"]; }
            set { base["minutes"] = value; }
        }
        public ProviderSettings this[int index]
        {
            get
            {
                return (ProviderSettings)base.BaseGet(index);
            }
            set
            {
                if (base.BaseGet(index) != null)
                {
                    base.BaseRemoveAt(index);
                }
                this.BaseAdd(index, value);
            }
        }

        public new ProviderSettings this[string key]
        {
            get
            {
                return (ProviderSettings)base.BaseGet(key);
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new ProviderSettings();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ProviderSettings)element).Name;
        }

    }
}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.