问题描述
我用 C# 编写了一个 Windows 服务,它基本上每分钟检查一次我的数据库中的订单,从这些订单生成一个 PDF,然后通过电子邮件发送.
I've written a Windows Service in C# that basically checks my db every minute for orders, generates a PDF from these orders, and emails it.
该逻辑在我的测试等中完美运行.
The logic works perfectly in my tests etc..
当我创建服务并使用安装项目安装它时,当我在服务 mmc 中启动该服务时,我得到:
When i create the service, and install it using the setup project, when I go to start the service in the services mmc, I get:
错误 1053 服务没有及时响应启动或控制请求
我的 OnStart 方法如下所示:
My OnStart method looks like this:
protected override void OnStart(string[] args)
{
//writeToWindowsEventLog("Service started", EventLogEntryType.Information);
timer.Enabled = true;
}
基本上,只需启用计时器...所以那里没有进程密集型调用.
Basically, just enables the timer... so theres no process intensive call there.
我哪里出错了?
我已经尝试将启动帐户设置为本地系统、网络服务等...没有任何效果!
I've tried setting the startup account to local system, network service etc... nothing works!
这是我的代码:(processPurchaseOrders 是查询数据库和生成 pdf 的方法等...)
Here is my code: (processPurchaseOrders is the method where the db is queried and pdf's are generated etc...)
public partial class PurchaseOrderDispatcher : ServiceBase
{
//this is the main timer of the service
private System.Timers.Timer timer;
public PurchaseOrderDispatcher()
{
InitializeComponent();
}
// The main entry point for the process
static void Main()
{
#if (!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new PurchaseOrderDispatcher() };
ServiceBase.Run(ServicesToRun);
#else //debug code
PurchaseOrderDispatcher service = new PurchaseOrderDispatcher();
service.processPurchaseOrders();
#endif
}
private void InitializeComponent()
{
this.CanPauseAndContinue = true;
this.ServiceName = "Crocus_PurchaseOrderGenerator";
}
private void InitTimer()
{
timer = new System.Timers.Timer();
//wire up the timer event
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
//set timer interval
var timeInSeconds = Convert.ToInt32(ConfigurationManager.AppSettings["TimerIntervalInSeconds"]);
timer.Interval = (timeInSeconds * 1000); // timer.Interval is in milliseconds, so times above by 1000
timer.Enabled = true;
}
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
components.Dispose();
base.Dispose(disposing);
}
protected override void OnStart(string[] args)
{
//instantiate timer
Thread t = new Thread(new ThreadStart(this.InitTimer));
t.Start();
}
protected override void OnStop()
{
//turn off the timer.
timer.Enabled = false;
}
protected override void OnPause()
{
timer.Enabled = false;
base.OnPause();
}
protected override void OnContinue()
{
timer.Enabled = true;
base.OnContinue();
}
protected void timer_Elapsed(object sender, ElapsedEventArgs e)
{
processPurchaseOrders();
}
}
推荐答案
来自 MSDN:
不要使用构造函数来执行应该在启动.使用 OnStart 处理服务的所有初始化.这构造函数在应用程序的可执行文件运行时调用,而不是在服务运行.可执行文件在 OnStart 之前运行.当你继续,例如,构造函数不会再次调用,因为SCM 已将对象保存在内存中.如果 OnStop 释放资源在构造函数中而不是在 OnStart 中分配,所需的第二次服务时不会再次创建资源叫.
如果您的计时器未在 OnStart 调用中初始化,这可能是一个问题.我还会检查计时器的类型,确保它是用于服务的 System.Timers.Timer.这里是如何在 Windows 服务中设置计时器.
If your timer is not initialized in the OnStart call, this could be a problem.I would also check the type of timer, make sure its a System.Timers.Timer for Services. Here is an example of how to setup the timer in a Windows service.
//TODONT:使用 Windows 服务只是为了运行一个预定的过程
我试过你的代码,看起来没问题.我唯一的区别是对计时器值 (Service1.cs) 进行硬编码.如果以下方法不起作用,请告诉我.
I tried your code, and it seems ok. The only difference I had was to hard code the timer value (Service1.cs). Let me know if the below doesn't work.
Service1.cs
Service1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using System.Threading;
namespace WindowsServiceTest
{
public partial class Service1 : ServiceBase
{
private System.Timers.Timer timer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
//instantiate timer
Thread t = new Thread(new ThreadStart(this.InitTimer));
t.Start();
}
protected override void OnStop()
{
timer.Enabled = false;
}
private void InitTimer()
{
timer = new System.Timers.Timer();
//wire up the timer event
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
//set timer interval
//var timeInSeconds = Convert.ToInt32(ConfigurationManager.AppSettings["TimerIntervalInSeconds"]);
double timeInSeconds = 3.0;
timer.Interval = (timeInSeconds * 1000);
// timer.Interval is in milliseconds, so times above by 1000
timer.Enabled = true;
}
protected void timer_Elapsed(object sender, ElapsedEventArgs e)
{
int timer_fired = 0;
}
}
}
Service1.Designer.cs
Service1.Designer.cs
namespace WindowsServiceTest
{
partial class Service1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "Service1";
this.CanPauseAndContinue = true;
}
#endregion
}
}
我刚刚创建了一个空白的 Windows 服务项目并添加了以下内容,以便我可以运行 installutil.exe 并附加到上面的内容以查看事件是否正在触发(确实如此).
I just created a blank Windows Service project and add the below so I could run installutil.exe and attach to the above to see if the event was firing (and it did).
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.ServiceProcess;
namespace WindowsServiceTest
{
[RunInstaller(true)]
public class MyServiceInstaller : System.Configuration.Install.Installer
{
public MyServiceInstaller()
{
ServiceProcessInstaller process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
ServiceInstaller serviceAdmin = new ServiceInstaller();
serviceAdmin.StartType = ServiceStartMode.Manual;
serviceAdmin.ServiceName = "Service1";
serviceAdmin.DisplayName = "Service1 Display Name";
Installers.Add(process);
Installers.Add(serviceAdmin);
}
}
}
这篇关于错误 1053 服务没有响应启动或控制请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!