使用Topshelf組件構(gòu)建簡單的Windows服務(wù)
很多時候都在討論是否需要了解一個組件或者一個語言的底層原理這個問題,其實我個人覺得,對于這個問題,每個人都有自己的看法,個人情況不同,選擇的方式也就會不同了。我個人覺得無論學(xué)習(xí)什么,都應(yīng)該嘗試著去了解對應(yīng)的原理和源碼(這里就不要急著吐槽,容我說完)。對底層的了解不是為了讓你寫出類似的東西,讓你寫也不可能寫的出來,重寫一個就需要以此修改整個底層結(jié)構(gòu),了解底層知識只是為了讓你可以在寫業(yè)務(wù)代碼時,選擇合適的方式,以此使底層與業(yè)務(wù)層配合達(dá)到效率最佳。任何一種方式有壞有好,需要合適的選擇。
如果覺得樓主以上的說法不對,或者有些不妥,還望見諒,因為爭論一個觀點(diǎn)沒有意義,認(rèn)為對的人自己會去理解,認(rèn)為不對的,可以忽略。沒有這個必要去花費(fèi)時間和精力取討論這種事情。
以上是扯淡,下面切入正題。前面介紹了一個組件Hangfire,用于設(shè)置定時任務(wù)等等操作,在這里介紹另一款組件Topshelf。
一.Topshelf組件概述
Topshelf是.NET平臺的Windows服務(wù)框架。Topshelf可以輕松創(chuàng)建Windows服務(wù),測試服務(wù),調(diào)試服務(wù),并最終將其安裝到Windows服務(wù)控制管理器(SCM)中。Topshelf通過允許開發(fā)人員專注于服務(wù)邏輯,而不是與.NET框架中的內(nèi)置服務(wù)支持交互的細(xì)節(jié)。開發(fā)人員不需要了解服務(wù)類的復(fù)雜細(xì)節(jié),通過InstallUtil執(zhí)行安裝,或者了解如何將調(diào)試器附加到服務(wù)以進(jìn)行故障排除問題。
創(chuàng)建Windows服務(wù)與創(chuàng)建控制臺應(yīng)用程序類似,控制臺應(yīng)用程序創(chuàng)建后,創(chuàng)建一個具有公共Start和Stop方法的單一服務(wù)類。服務(wù)操作的方式較多,自動,自動(延遲),手動和禁用啟動選項本地系統(tǒng),本地服務(wù),網(wǎng)絡(luò)服務(wù),用戶名/密碼或安裝期間提示的服務(wù)憑證。服務(wù)啟動依賴項,包括SQL Server,MSMQ和其他具有不同服務(wù)名稱的多實例服務(wù)安裝服務(wù)恢復(fù)選項,包括重新啟動,重新引導(dǎo)或運(yùn)行程序。Topshelf與Mono合作,可以將服務(wù)部署到Linux。服務(wù)安裝功能目前僅限Windows。
二.Topshelf用法說明
介紹完對應(yīng)的組件背景概述,在這里就要介紹一下如何使用這個組件的使用方法。該組件的使用方法有另個方法,都在HostFactory類中,下面具體的介紹一個使用方式。
1.配置新的服務(wù)主機(jī)
HostFactory.New(x =>
{
// 可以定義不需要接口依賴性的服務(wù),這只是為了
//在此示例中顯示并未使用。
x.Service<SampleSansInterfaceService>(s =>
{
s.ConstructUsing(() => new SampleSansInterfaceService());
s.WhenStarted(v => v.Start());
s.WhenStopped(v => v.Stop());
});
});
2.配置和運(yùn)行新的服務(wù)主機(jī),處理任何異常并將其寫入日志
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配置操作方法

三.Topshelf核心對象解析
承接上文,介紹完畢相關(guān)背景和常規(guī)操作,在這里介紹一個核心對象的一些方法。
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;
}
}
該方法用于配置新的服務(wù)主機(jī),方法接受一個參數(shù)Action<HostConfigurator>配置方法調(diào)用,該方法返回Host對象,表示Topshelf服務(wù)主機(jī),準(zhǔn)備運(yùn)行。 configureCallback.Method.DeclaringType;用于獲取聲明該成員的類。declaringType.Namespace;用于獲取獲取 System.Type 的命名空間。ValidateConfigurationResult.CompileResults(configurator.Validate());用于驗證配置結(jié)果。
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;
}
}
該方法是一個靜態(tài)方法,配置和運(yùn)行新的服務(wù)主機(jī),處理任何異常并將其寫入日志。該方法接收一個參數(shù)Action<HostConfigurator> configureCallback配置方法調(diào)用,返回應(yīng)用程序主方法返回的進(jìn)程的退出代碼。
四.總結(jié)
以上是介紹如何使用Topshelf組件創(chuàng)建簡單的Windows服務(wù)的方法,在這里只是一個簡單的介紹,沒有很深入的介紹,如果需要了解更多的東西,可以看源碼,畢竟是開源免費(fèi)的組件,也是一個很不錯的組件。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
asp.net 將一個圖片以二進(jìn)制值的形式存入Xml文件中的實例代碼
這篇文章介紹了將一個圖片以二進(jìn)制值的形式存入Xml文件中的實例代碼,有需要的朋友可以參考一下2013-07-07
ASP.NET百度Ueditor編輯器實現(xiàn)上傳圖片添加水印效果
這篇文章主要給大家介紹了ASP.NET百度Ueditor編輯器1.4.3這個版本實現(xiàn)上傳圖片添加水印效果的相關(guān)資料,文中通過圖文及示例代碼介紹的非常詳細(xì),相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。2017-03-03
.NET?如何使用?OpenTelemetry?metrics?監(jiān)控應(yīng)用程序指標(biāo)
這篇文章主要介紹了.NET?使用?OpenTelemetry?metrics?監(jiān)控應(yīng)用程序指標(biāo),通過代碼演示了如何通過 OpenTelemetry 把 Metrics 的數(shù)據(jù)發(fā)送到 Prometheus 里進(jìn)行查詢與展示,然后又演示了自定義相關(guān)指標(biāo)來滿足業(yè)務(wù)數(shù)據(jù)指標(biāo)的監(jiān)控,需要的朋友可以參考下2024-06-06
asp.net jQuery Ajax用戶登錄功能的實現(xiàn)
前幾天把jbox源碼修改成仿QQ空間模擬窗口后發(fā)現(xiàn)有很多人在關(guān)注。今天就貼一下我利用該模擬窗口實現(xiàn)的用戶登錄功能的代碼。2009-11-11
ASP.NET.4.5.1+MVC5.0設(shè)置系統(tǒng)角色與權(quán)限(二)
這篇文章主要介紹了使用ASP.NET.4.5.1+MVC5.0構(gòu)建項目中設(shè)置系統(tǒng)角色的全部過程,十分的詳細(xì),附上全部源碼,推薦給想學(xué)習(xí).net+mvc的小伙伴們2015-01-01
asp.net動態(tài)產(chǎn)生checkbox(數(shù)據(jù)源為DB或內(nèi)存集合)
動態(tài)產(chǎn)生一組checkbox(數(shù)據(jù)源為DB或內(nèi)存集合)且post提交時后臺能及時獲取等等,打算使用repeater+input(checkbox)+input(hidden)來實現(xiàn)2013-10-10
C# 接口的隱式與顯示實現(xiàn)及適應(yīng)場景
以前在用到接口時,從來沒注意到接口分為隱式實現(xiàn)與顯示實現(xiàn)。昨天在瀏覽博客時看到相關(guān)內(nèi)容,現(xiàn)在根據(jù)自己的理解記錄一下,方便日后碰到的時候溫習(xí)溫習(xí),需要的朋友可以了解下2012-12-12

