C# 如何使windows服务保持活动状态?

C# 如何使windows服务保持活动状态?,c#,windows-services,C#,Windows Services,我制作了一个简单的windows服务,但当我尝试启动它时,它会立即关闭,并显示以下消息: 本地计算机上的ConsumerService服务已启动,然后停止。如果某些服务未被其他服务或程序使用,则会自动停止 以下是我尝试运行的服务: static class Program { /// <summary> /// The main entry point for the application. /// </summary> static v

我制作了一个简单的windows服务,但当我尝试启动它时,它会立即关闭,并显示以下消息:

本地计算机上的ConsumerService服务已启动,然后停止。如果某些服务未被其他服务或程序使用,则会自动停止

以下是我尝试运行的服务:

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)。您仍然需要捕获错误(例如,文件被其他进程锁定,没有权限等),但不必担心关闭它。