C#Windows服务:该服务没有响应开始

时间:2011-07-20 19:34:03

标签: c# multithreading windows-services

这是我第一次尝试创建一个调用多个线程的Windows服务。我做的是创建一个控制台应用程序,然后添加一个Windows服务和安装程序。我的代码如下。

partial class Service1 : ServiceBase
{
    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        System.Timers.Timer timer1 = new System.Timers.Timer();
        timer1.Interval = 10000;
        timer1.Start();
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
    }

    public static void timer1_Elapsed(object sender, EventArgs e)
    {
        Program.ThreadController();   
    }

    protected override void OnStop()
    {
        // TODO: Add code here to perform any tear-down necessary to stop your service.
    }
}

class Program
{
    static void Main(string[] args)
    {
        ThreadController();
    }

    public static void ThreadController()
    {
        for (int i = 0; i < 3; i++)
        {
            new Thread(() => { processEventLogTesting(); });
        }
    }

    public static void processEventLogTesting()
    {
        EventLog.WriteEntry("ProcessThread1", "Process1 Works");
    }
}

我不确定为什么我会收到此错误,任何提示都会很棒。

感谢。

5 个答案:

答案 0 :(得分:4)

processEventLogTesting ()中有无限递归。这就是它没有回应的原因。当我使用计时器编写Windows服务时,我所做的就是连接回调并在OnStart中启动计时器。然后我坐下来让它做它的事情。你试图在启动时做太多。

答案 1 :(得分:1)

首先,我添加了一些调试功能。它实际上很容易(当你知道如何!!!)。

将此添加到您的班级:

[DllImport("kernel32.dll")]
public static extern Int32 AllocConsole();

然后将其添加到您的main函数中(如果您启用服务以便访问用户界面,那么当您作为服务运行时也可以这样做。)

for (int loop = 0; loop < args.Count; loop++)
{
  if (args[loop] == "debug")
    AllocConsole();
}

这为您提供了一个控制台窗口,您可以使用Console.WriteLine立即向其发送输出。美味。

现在你想要实现的是服务控制管理器调用你的OnStart方法,然后该方法必须返回OK信号让SCM知道你的应用程序启动正常。否则,SCM认为出了问题并杀死了你的应用程序。所以OnStart应该启动你的线程。因此,创建一个由您的线程(和Main)运行的Run()方法,并使OnStart尽可能快地返回。

我注意到我的代码示例中没有看到任何内容:

System.ServiceProcess.ServiceBase [] ServicesToRun; ServicesToRun = new System.ServiceProcess.ServiceBase [] {new WinService1()}; System.ServiceProcess.ServiceBase.Run(ServicesToRun);

我怀疑您的应用没有向SCM报告它已成功启动了可执行文件中的“服务”。

您希望您的应用程序启动,将“服务”交给SCM并让它知道您没事,然后返回,而您的服务现在正在使用自己的线程运行。

请参阅此文章,了解更多信息: http://msdn.microsoft.com/en-us/library/aa984464(v=vs.71).aspx

答案 2 :(得分:0)

 partial class Service1 : ServiceBase
 {
    private Program program;

    public Service1()
    {
        InitializeComponent();
        program = new Program ();
    }

    protected override void OnStart(string[] args)
    {
        program.Start ();
    }

    protected override void OnStop()
    {
        program.Stop ();
    }
}

class Program
{
    private Systems.Timers.Timer timer;

    public Program ()
    {
        timer = new System.Timers.Timer ();
        timer.Interval = 10000;
        timer.Elapsed += new ElapsedEventHandler (timer_Elapsed);

    }

    public void Start () 
    {
        timer.Enabled = true;
    }

    public void Stop ()
    {
        timer.Enabled = false;
    }

    public static void timer_Elapsed (object sender, EventArgs e)
    {
        EventLog.WriteEntry ("ProcessThread1", "Process1 Works");
    }
}

答案 3 :(得分:0)

  1. 您没有在代码中启动线程,因此:

    for (int i = 0; i < 3; i++)
    {
        new Thread(() => { processEventLogTesting(); }) { IsBackground = true }.Start();
    }
    
  2. 除了错误的递归通话之外,在你的processEventLogTesting(),您正在创建一个计时器,然后只需timer1 = new System.Timers.Timer();覆盖它,这样就不会触发。

    public static void processEventLogTesting()
    {
        System.Timers.Timer timer1 = new System.Timers.Timer();
        timer1.Interval = 10000;
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
        timer1.Start();
    }
    

答案 4 :(得分:-1)

Windows服务非常难以调试。如果您没有收到任何其他消息,请尝试在onstart上暂停,您应该能够附加到它,然后看看问题是什么。

Nik在这里有答案,但这可能对其他Windows服务有用!