.NET Windows服务中存储设置的最佳实践:服务属性设置、序列化。

12
我正在开发一个.NET Windows服务,尝试存储在服务启动和运行期间将使用的设置。我在SO上搜索过,并发现在项目属性中使用设置非常适用于控制台和WinForms应用程序。但是,当涉及在Windows服务中存储这些设置时,Google和SO都没有提到。
有人知道是否可以在.NET服务中使用这些设置吗?如果不行,那序列化是我的下一个最佳选择吗?有人在服务中使用设置时有实际用途并发现最好使用特定方法吗?
4个回答

13

我曾经在使用Settings.settings时遇到过问题。例如,如果您需要在运行时进行更改,则可能会出现问题,因为设置被最初存储在settings.settings文件中的设置覆盖了,而不是像应该存储在应用程序/ web.config中的设置。因此,我将所有Web服务代理设置为“静态”属性,并通过辅助方法手动从app / web.config中提取它们,然后以编程方式设置它们。这样可以避免任何问题。

我们遇到的一个问题的例子是:我将我的开发机器指向测试服务器上的Web服务,以测试消耗Web服务的代码。当将该代码移动到测试服务器时,没有出现问题-因为测试服务器仍然指向同一测试服务器上的同一Web服务。但是,当我们将应用程序移动到生产服务器并重新配置web.config以指向生产服务器时,我们开始出现错误结果。经过相当多的努力,才确定即使我们已将应用程序重新配置为指向生产服务器上的Web服务实现,它仍在连接到测试服务器上的Web服务。直到我们更改了我的开发计算机上的settings.settings并重新编译应用程序,它才起作用。此外,我们还注意到,如果在连接到生产Web服务时存在DNS问题,它不会失败,而是退回到在应用程序中创建Web服务代理时指定的原始设置-代理生成器实际上将其硬编码。因此,在存在网络故障时,它不会轻易被诊断为连接失败,而是简单地回到测试服务器,并且我们开始出现难以理解的数据问题。我不确定这是否是已知问题或是否已修复,但这确实是您应该注意的事项。

因此,从那以后,我总是将服务属性设置为静态,并使用辅助方法直接从web.config中读取正确的设置,然后以编程方式写入它们,因为这似乎可以避免问题。

我遇到的问题似乎与你的问题无关,因为我使用的是Web Services,而这与Windows Services没有任何关系。然而,在任何需要能够在运行时更改设置而不必重新编译的环境中,都可能受到此问题的影响,因此,你应该意识到,如果你在Dev/Test/Production环境或任何需要在运行时重新配置应用程序的环境中运行,那么在使用settings.settings时可能会得到不可预测的结果。请注意。


非常感谢您提供如此详细的答案。我想给您点赞,但是我还没有足够的声望积分。感谢您抽出时间来回答这个问题。 - TheDevOpsGuru
1
我必须承认,我根本没有遇到过这些问题,我们使用了很多从app.config文件中读取的应用程序设置的Windows服务,包括Web服务URL。 您认为这个问题是特定于Windows服务v Win Forms应用程序,还是一个普遍的app.config错误/问题? - barrylloyd
@barrylloyd - 老实说,我没有进行太多的调查,因为这是一个关键任务应用程序[即修复并继续前进]。从我所做的调查来看,似乎问题可能涉及Web服务代理与settings.settings的交互,而不是正确连接到web.config以查找其设置。它可能只影响框架的这个区域,也可能影响其他区域,我不确定。 - BenAlabaster
@barrylloyd @benAlabaster,我认为问题在于你们如何访问设置。我认为是这样的:如果你在VB.Net中使用My.Settings来访问它们,它会从.config文件中读取设置,但是如果你在C#中使用类似的方式(Settings.Default),那么你将读取编译在默认设置中的设置。为了避免这种情况发生在C#中,您需要创建一个设置对象的实例。当需要时重新加载和保存设置也很重要(我通常在OnStart和OnStop中进行)。 - Hans Olsson
抱歉打扰,但我想指出,为了覆盖默认设置,您必须在“Host”程序集中这样做。基本上无论您的Program Main()在哪里,或者global.asax,或者Startup.cs。您需要将<class library>中的<configSections><sectionGroup name="applicationSettings"><section name="YourApp.Properties.Settings">复制到您的主app.config中,然后您可以在主app.config中的<applicationSettings><YourApp.Properties.Settings>部分中覆盖必要的部分。希望这有所帮助/有意义。 - mikesigs

9
我通常使用注册表来存储我在服务中需要的信息,例如端口等。
string lsbkey = @"Software\mycompany\adas";

RegistryKey adaskey = Registry.LocalMachine.OpenSubKey(lsbkey, false);

try
{
    object regip = adaskey.GetValue("IP");
    object regport = adaskey.GetValue("PORT");
    localip = regip.ToString();
    localport = int.Parse(regport.ToString());
}
catch (NullReferenceException ne)
{
    localip = null;
    localport = 0;
    writelog(@"Aborting Service, IP or PORT doesn't exist in \local machine\software\mycompany\adas : "+ne.Message);
    status = 0;

}

5
我使用Settings.settings存储我的服务配置,没有遇到过问题。只有用户更改的设置会存储在它通常难以找到的位置中,如果您想手动编辑它们,就必须四处搜寻。

0

我认为在项目属性中使用设置与WinForms应用程序一样,没有任何不可行的理由。我们经常这样做,而且效果很好。


8
在属性中使用设置的问题在于它依赖于已登录用户,因为设置存储在用户配置文件中。如果多个管理员正在使用服务,则设置会发生更改。 - Amr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接