C# 如何使windows服务保持活动状态?
我制作了一个简单的windows服务,但当我尝试启动它时,它会立即关闭,并显示以下消息: 本地计算机上的ConsumerService服务已启动,然后停止。如果某些服务未被其他服务或程序使用,则会自动停止 以下是我尝试运行的服务:C# 如何使windows服务保持活动状态?,c#,windows-services,C#,Windows Services,我制作了一个简单的windows服务,但当我尝试启动它时,它会立即关闭,并显示以下消息: 本地计算机上的ConsumerService服务已启动,然后停止。如果某些服务未被其他服务或程序使用,则会自动停止 以下是我尝试运行的服务: static class Program { /// <summary> /// The main entry point for the application. /// </summary> static v
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
var servicesToRun = new ServiceBase[]
{
new ConsumerService()
};
ServiceBase.Run(servicesToRun);
}
}
public partial class ConsumerService : ServiceBase
{
private readonly MessageConsumer<ClickMessage> _messageconsumer;
private readonly SqlRepository _sqlrep;
private static Timer _timer;
public ConsumerService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
File.Create(@"c:\ErrorLog.txt");
WriteToFile("Has started : " + DateTime.UtcNow);
var t = new Timer(OnTimeEvent, null, 1000, 1000);
}
catch (Exception e)
{
WriteToFile("Error : " + e.Message);
}
}
private void OnTimeEvent(object state)
{
WriteToFile("The time is : " + DateTime.UtcNow);
}
protected override void OnStop()
{
WriteToFile("Has stopped : " + DateTime.UtcNow);
}
private static void WriteToFile(string s)
{
var stream = File.AppendText(@"c:\ErrorLog.txt");
stream.WriteLine(s);
}
}
静态类程序
{
///
///应用程序的主要入口点。
///
静态void Main()
{
var servicesToRun=new ServiceBase[]
{
新消费者服务()
};
ServiceBase.Run(servicesToRun);
}
}
公共部分类ConsumerService:ServiceBase
{
私有只读消息消费者_MessageConsumer;
私有只读SqlRepository\u sqlrep;
专用静态定时器_定时器;
公共消费者服务()
{
初始化组件();
}
启动时受保护的覆盖无效(字符串[]args)
{
尝试
{
创建(@“c:\ErrorLog.txt”);
WriteToFile(“已开始:+DateTime.UtcNow”);
var t=新计时器(OnTimeEvent,null,1000,1000);
}
捕获(例外e)
{
WriteToFile(“错误:+e.Message”);
}
}
私有void OnTimeEvent(对象状态)
{
WriteToFile(“时间为:“+DateTime.UtcNow”);
}
受保护的覆盖void OnStop()
{
WriteToFile(“已停止:“+DateTime.UtcNow”);
}
私有静态void WriteToFile(字符串s)
{
var stream=File.AppendText(@“c:\ErrorLog.txt”);
流.写线(s);;
}
}
正如您所看到的,这只是一个简单的计时器,它每1秒向一个文件写入一行,所以我很困惑为什么这会阻止服务运行。我也很难看出windows提供的消息与此服务有何关联,因为这会阻止任何服务运行,除非某些东西已经依赖它。来自:
只要使用计时器,就必须保留对它的引用。作为
对于任何托管对象,计时器在
没有提到它。计时器仍处于活动状态的事实
不会阻止它被收集
您不保留对计时器对象的任何引用
尝试更改此选项:
private static Timer _timer;
为此:
private Timer _timer;
_timer = new Timer(OnTimeEvent, null, 1000, 1000);
这是:
var t = new Timer(OnTimeEvent, null, 1000, 1000);
为此:
private Timer _timer;
_timer = new Timer(OnTimeEvent, null, 1000, 1000);
这很可能是由于主线程中存在未处理的错误。要验证这一点,请检查事件日志,但从代码的快速查看功能WriteToFile
有可能崩溃并导致整个服务崩溃
实际上,它应该崩溃,因为您让流保持打开状态(因此文件被锁定),第二次尝试打开它将导致错误
将代码更改为此,它将防止此类崩溃,并修复使文件保持锁定的错误:
private static void WriteToFile(string s)
{
try
{
using (var stream = File.AppendText(@"c:\ErrorLog.txt"))
{
stream.WriteLine(s);
stream.Close();
}
}
catch (Exception e)
{
Console.WriteLine("error writing to file: " + e);
//...or any other means of external debug...
}
}
正如我所看到的,你的代码正在结束。。。因此,程序的执行自然结束。这就是为什么您的服务也会停止,因为它的执行已经结束。您的代码运行一次后就会关闭。就像你写的那样工作。@Ramhound-我确信计时器实际上是在InitializeComponent()中启动的代码>方法调用。然后代码将运行多次。他可能只是在帖子中省略了代码,但是有一个方法捕获了OnTimeEvent
,所以你可以想象他已经对这部分内容进行了排序。除此之外,显然在创建文件时我还必须关闭流,所以:file.Create(@“c:\ErrorLog.txt”)代码>更改为:File.Create(@“c:\ErrorLog.txt”).Close()是的,我错过了那个。通常,除非您有充分的理由使用流,否则我建议您使用File
类静态方法,如File.writealText()
来创建文件而不必担心锁定,使用File.AppendAllText()
来追加文本而不必担心流和锁定。要模拟WriteLine()
您只需将Environment.NewLine添加到您附加的内容中,例如File.AppendAllText(@“c:\ErrorLog.txt”,s+Environment.NewLine)代码>。您仍然需要捕获错误(例如,文件被其他进程锁定,没有权限等),但不必担心关闭它。