C# 为什么我的计时器是';从未触发的已过事件?

C# 为什么我的计时器是';从未触发的已过事件?,c#,timer,windows-services,elapsed,C#,Timer,Windows Services,Elapsed,我在Windows服务中获得了以下代码: public void ConfigureService() { //timer = new Timer { Interval = 600000 }; timer = new Timer { Interval = 10000 }; // 10 minutes; 1 second while testing timer.Elapsed += timer_Tick; timer.Enabled = true;

我在Windows服务中获得了以下代码:

public void ConfigureService()
{
    //timer = new Timer { Interval = 600000 };
    timer = new Timer { Interval = 10000 };
    // 10 minutes; 1 second while testing
    timer.Elapsed += timer_Tick;
    timer.Enabled = true;
    RoboRprtrLib.WriteToLog("RoboRprtrService has started");
}

private void timer_Tick(object sender, ElapsedEventArgs eeargs)
{
    timer.Elapsed -= timer_Tick;
    try
    {
        RoboRprtrLib.WriteToLog("Timer has ticked");
        RoboRprtrLib.GenerateAndEmailDueReports();
    }
    finally
    {
        timer.Elapsed += timer_Tick;
    }
}
从Program.cs调用ConfigureService():

static void Main()
{
    // got this idea ("How to Debug or Test your Windows Service Without Installing it...") from http://www.codeproject.com/Tips/261190/How-to-Debug-or-Test-your-Windows-Service-Without
    #if(!DEBUG)
    var ServicesToRun = new ServiceBase[] 
    { 
        new RoboRprtrService() 
    };
    ServiceBase.Run(ServicesToRun);
    #else
    var rrs = new RoboRprtrService();
    rrs.ConfigureService();
    #endif
}
我在这一行的ConfigureService()中有一个断点:

timer = new Timer { Interval = 10000 };
RoboRprtrLib.GenerateAndEmailDueReports();
它已经到达;我可以逐步完成整个ConfigureService()方法

我在第一行的“经过/滴答”事件中有一个断点:

timer.Elapsed -= timer_Tick;
…而且永远也达不到

为什么不呢?计时器不是设置为10秒后跳闸吗?在这一点上应该调用Tick事件处理程序

更新 这是从ServiceBase派生的类的完整代码:

public partial class RoboRprtrService : ServiceBase
{
    private Timer timer;

    public RoboRprtrService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        ConfigureService();
    }

    public void ConfigureService()
    {
        //timer = new Timer { Interval = 600000 };
        timer = new Timer { Interval = 50000 };
        // 10 minutes; 50 seconds while testing
        timer.Elapsed += timer_Tick;
        timer.Enabled = true;
        RoboRprtrLib.WriteToLog("RoboRprtrService has started");
    }

    private void timer_Tick(object sender, ElapsedEventArgs eeargs)
    {
        timer.Elapsed -= timer_Tick;
        try
        {
            RoboRprtrLib.WriteToLog("Timer has ticked");
            RoboRprtrLib.GenerateAndEmailDueReports();
        }
        finally
        {
            timer.Elapsed += timer_Tick;
        }
    }

    protected override void OnStop()
    {
        timer.Enabled = false;
        RoboRprtrLib.WriteToLog("RoboRprtrService has stopped");
    }

}
更新2 我觉得很奇怪,但如果我加上这一行:

timer = new Timer { Interval = 10000 };
RoboRprtrLib.GenerateAndEmailDueReports();
…在ConfigureService()方法结束时,计时器最终会触发

更新3 更奇怪的是:我得到了关于需要添加STAThread属性的错误消息(并且调用了一个不应该调用的方法,这导致了它失败和服务崩溃)。所以我在Program.cs中用“[STAThread]”修饰Main(),现在它可以正常工作了

在操作过程中计时器跳了几次,但如果正在进行处理,我有代码要退出。当调用的方法完成时,IDE“闪烁”起来,好像在说:“呸!我要离开这里!”

因此,我的Program.cs代码现在是:

[STAThread]
static void Main()
{
    #if(!DEBUG)
    var ServicesToRun = new ServiceBase[] 
    { 
        new RoboRprtrService() 
    };
    ServiceBase.Run(ServicesToRun);
    #else
    var rrs = new RoboRprtrService();
    rrs.ConfigureService();
    Console.ReadLine();
    #endif
}
…从ServiceBase派生的类中最相关的代码是:

public void ConfigureService()
{
    //timer = new Timer { Interval = 600000 };
    timer = new Timer { Interval = 50000 };
    // 10 minutes; 50 seconds while testing
    timer.Elapsed += timer_Tick;
    timer.Enabled = true;
    RoboRprtrLib.WriteToLog("RoboRprtrService has started");
    operationIsRunning = true;
    RoboRprtrLib.GenerateAndEmailDueReports();
    operationIsRunning = false;
}

private void timer_Tick(object sender, ElapsedEventArgs eeargs)
{
    if (operationIsRunning) return;
    operationIsRunning = true;
    . . .
在我上次运行GenerateAndEmailDueReports()时,tick处理程序中的“if(OperationRunning)return;”断点在执行GenerateAndEmailDueReports()的过程中达到了三次,每次它都按设计返回。

如注释中所述,在调试模式下,您的代码将在调用
ConfigureService
后立即终止,因此,没有时间执行
计时器

在发布模式下
ServiceBase.Run
阻塞线程,直到服务完成,但在调试版本中不会发生这种情况

编辑:

实际上,我尝试了
Console.ReadLine()
,但没有停止,显然标准输入被重定向,只是尝试保持进程运行,使用无限循环或其他方式

像这样:

static void Main()
{
    // got this idea ("How to Debug or Test your Windows Service Without Installing it...") from http://www.codeproject.com/Tips/261190/How-to-Debug-or-Test-your-Windows-Service-Without
    #if(!DEBUG)
    var ServicesToRun = new ServiceBase[] 
    { 
        new RoboRprtrService() 
    };
    ServiceBase.Run(ServicesToRun);
    #else
    var rrs = new RoboRprtrService();
    rrs.ConfigureService();

    while (true)
        Thread.Sleep(100);
    #endif
}

10000
为10秒。呃,你应该等得够久吗?我也试了几分钟,但也没用。如果你能提供一个而不是所有这些片段,那会很有帮助。例如,我们无法判断计时器是否存储在符合垃圾收集条件的对象的字段中。我强烈怀疑您不需要使用Windows服务来演示这一点。在本例中,
Timer
的全名是什么?Main()方法没有经过很好的考虑,计时器永远不会滴答作响。在调试生成中,程序将在调用ConfigureService()后立即终止。也许可以添加Console.ReadLine()。这方面的教训是最好不要从随机文章中复制随机代码,而只是希望它能够工作。在Main()中的“rrs.ConfigureService();”之后添加“Console.ReadLine();”,不会导致计时器跳闸;但是,在ConfigureService()中调用“RoboRprtrLib.GenerateAndEmailDueReports();”会发生这种情况。为什么,我不知道。