使用Topshelf組件構建簡單的Windows服務

   不少時候都在討論是否須要瞭解一個組件或者一個語言的底層原理這個問題,其實我我的以爲,對於這個問題,每一個人都有本身的見解,我的狀況不一樣,選擇的方式也就會不一樣了。我我的以爲不管學習什麼,都應該嘗試着去了解對應的原理和源碼(這裏就不要急着吐槽,容我說完)。對底層的瞭解不是爲了讓你寫出相似的東西,讓你寫也不可能寫的出來,重寫一個就須要以此修改整個底層結構,瞭解底層知識只是爲了讓你能夠在寫業務代碼時,選擇合適的方式,以此使底層與業務層配合達到效率最佳。任何一種方式有壞有好,須要合適的選擇。網絡

  若是以爲樓主以上的說法不對,或者有些不妥,還望見諒,由於爭論一個觀點沒有意義,認爲對的人本身會去理解,認爲不對的,能夠忽略。沒有這個必要去花費時間和精力取討論這種事情。框架

  以上是扯淡,下面切入正題。前面介紹了一個組件Hangfire,用於設置定時任務等等操做,在這裏介紹另外一款組件Topshelf。學習

一.Topshelf組件概述

   Topshelf是.NET平臺的Windows服務框架。Topshelf能夠輕鬆建立Windows服務,測試服務,調試服務,並最終將其安裝到Windows服務控制管理器(SCM)中。Topshelf經過容許開發人員專一於服務邏輯,而不是與.NET框架中的內置服務支持交互的細節。開發人員不須要了解服務類的複雜細節,經過InstallUtil執行安裝,或者瞭解如何將調試器附加到服務以進行故障排除問題。測試

   建立Windows服務與建立控制檯應用程序相似,控制檯應用程序建立後,建立一個具備公共Start和Stop方法的單一服務類。服務操做的方式較多,自動,自動(延遲),手動和禁用啓動選項本地系統,本地服務,網絡服務,用戶名/密碼或安裝期間提示的服務憑證。服務啓動依賴項,包括SQL Server,MSMQ和其餘具備不一樣服務名稱的多實例服務安裝服務恢復選項,包括從新啓動,從新引導或運行程序。Topshelf與Mono合做,能夠將服務部署到Linux。服務安裝功能目前僅限Windows。google

二.Topshelf用法說明

      介紹完對應的組件背景概述,在這裏就要介紹一下如何使用這個組件的使用方法。該組件的使用方法有另個方法,都在HostFactory類中,下面具體的介紹一個使用方式。spa

   1.配置新的服務主機調試

      HostFactory.New(x =>
                {
                    // 能夠定義不須要接口依賴性的服務,這只是爲了
                    //在此示例中顯示並未使用。
                    x.Service<SampleSansInterfaceService>(s =>
                        {
                            s.ConstructUsing(() => new SampleSansInterfaceService());
                            s.WhenStarted(v => v.Start());
                            s.WhenStopped(v => v.Stop());
                        });
                });

   2.配置和運行新的服務主機,處理任何異常並將其寫入日誌日誌

   HostFactory.Run(x =>
                {
                    x.UseLog4Net("log4net.config");
                    x.UseAssemblyInfoForServiceInfo();
                    bool throwOnStart = false;
                    bool throwOnStop = false;
                    bool throwUnhandled = false;
                    x.Service(settings => new SampleService(throwOnStart, throwOnStop, throwUnhandled), s =>
                    {
                        s.BeforeStartingService(_ => Console.WriteLine("BeforeStart"));
                        s.BeforeStoppingService(_ => Console.WriteLine("BeforeStop"));
                    });
                    x.SetStartTimeout(TimeSpan.FromSeconds(10));
                    x.SetStopTimeout(TimeSpan.FromSeconds(10));
                    x.EnableServiceRecovery(r =>
                        {
                            r.RestartService(3);
                            r.RunProgram(7, "ping google.com");
                            r.RestartComputer(5, "message");

                            r.OnCrashOnly();
                            r.SetResetPeriod(2);
                        });
                    x.AddCommandLineSwitch("throwonstart", v => throwOnStart = v);
                    x.AddCommandLineSwitch("throwonstop", v => throwOnStop = v);
                    x.AddCommandLineSwitch("throwunhandled", v => throwUnhandled = v);
                    x.OnException((exception) =>
                    {
                        Console.WriteLine("Exception thrown - " + exception.Message);
                    });
                });

    3.Topshelf配置操做方法code

三.Topshelf核心對象解析

     承接上文,介紹完畢相關背景和常規操做,在這裏介紹一個核心對象的一些方法。orm

  1.HostFactory.New():

public static Host New(Action<HostConfigurator> configureCallback)
        {
            try
            {
                if (configureCallback == null)
                    throw new ArgumentNullException("configureCallback");
                var configurator = new HostConfiguratorImpl();
                Type declaringType = configureCallback.Method.DeclaringType;
                if (declaringType != null)
                {
                    string defaultServiceName = declaringType.Namespace;
                    if (!string.IsNullOrEmpty(defaultServiceName))
                        configurator.SetServiceName(defaultServiceName);
                }
                configureCallback(configurator);
                configurator.ApplyCommandLine();
                ConfigurationResult result = ValidateConfigurationResult.CompileResults(configurator.Validate());
                if (result.Message.Length > 0)
                {
                    HostLogger.Get(typeof(HostFactory))
                              .InfoFormat("Configuration Result:\n{0}", result.Message);
                }
                return configurator.CreateHost();
            }
            catch (Exception ex)
            {
                HostLogger.Get(typeof(HostFactory)).Error("An exception occurred creating the host", ex);
                HostLogger.Shutdown();
                throw;
            }
        }

     該方法用於配置新的服務主機,方法接受一個參數Action<HostConfigurator>配置方法調用,該方法返回Host對象,表示Topshelf服務主機,準備運行。 configureCallback.Method.DeclaringType;用於獲取聲明該成員的類。declaringType.Namespace;用於獲取獲取 System.Type 的命名空間。ValidateConfigurationResult.CompileResults(configurator.Validate());用於驗證配置結果。

   2.HostFactory.Run():

public static TopshelfExitCode Run(Action<HostConfigurator> configureCallback)
        {
            try
            {
                return New(configureCallback)
                    .Run();
            }
            catch (Exception ex)
            {
                HostLogger.Get(typeof(HostFactory))
                          .Error("The service terminated abnormally", ex);
                HostLogger.Shutdown();
                
                return TopshelfExitCode.AbnormalExit;
            }
        }

     該方法是一個靜態方法,配置和運行新的服務主機,處理任何異常並將其寫入日誌。該方法接收一個參數Action<HostConfigurator> configureCallback配置方法調用,返回應用程序主方法返回的進程的退出代碼。

四.總結

   以上是介紹如何使用Topshelf組件建立簡單的Windows服務的方法,在這裏只是一個簡單的介紹,沒有很深刻的介紹,若是須要了解更多的東西,能夠看源碼,畢竟是開源免費的組件,也是一個很不錯的組件。

相關文章
相關標籤/搜索