Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# windows服务中方法的同步执行_C#_.net - Fatal编程技术网

C# windows服务中方法的同步执行

C# windows服务中方法的同步执行,c#,.net,C#,.net,我正在编写一个windows服务,以每x分钟执行一个方法,但我希望该方法相对于计时器本身同步执行。windows服务有一个计时器对象(System.Timers.Timer),它每x分钟启动并调用一个方法“DoWork”,但计时器必须在“DoWork”执行时“停止”,并在方法完成后再次启动 我知道使用System.Windows.Forms.Timer类将提供我想要的行为,但我不想将System.Windows.Forms dll引用添加到我的服务项目中 以下是“工作”代码的示例: pr

我正在编写一个windows服务,以每x分钟执行一个方法,但我希望该方法相对于计时器本身同步执行。windows服务有一个计时器对象(System.Timers.Timer),它每x分钟启动并调用一个方法“DoWork”,但计时器必须在“DoWork”执行时“停止”,并在方法完成后再次启动

我知道使用System.Windows.Forms.Timer类将提供我想要的行为,但我不想将System.Windows.Forms dll引用添加到我的服务项目中

以下是“工作”代码的示例:

    private System.Timers.Timer timer1;

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

    void timer1_Elapsed(object sender, ElapsedEventArgs e)
    {
        timer1.Stop();
        DoWork();
        timer1.Start();
    }

    private void DoWork()
    {
        Thread.Sleep(2000);
        Console.WriteLine("found!");
    }
在上面的控制台应用程序中运行(作为编写windows服务之前的模型),预期的行为应该是控制台写入“found!”每3秒

附带说明:我只是使用“Thread.Sleep(2000)”来模拟延迟,但它不会构成实际代码库的一部分

有没有比我上面的方法更好的方法


感谢阅读我的问题,如果您有任何意见,我们将不胜感激。

您不能在windows服务中使用
System.Forms.Timer
,因为这需要一个消息泵,windows服务没有一个非常大的消息泵堆栈(另外,您必须调用
应用程序。运行
启动一个)


现在的方式是我实现周期性事件的方式。我想添加一些东西来监控您的事件是否比周期长;但除此之外…

您遇到的主要问题似乎被描述为“计时器必须在“DoWork”执行时“停止”,并在方法完成后再次启动”。简而言之,服务需要是多线程的。您应该考虑使用线程池。使用线程池将允许您的执行线程继续计算时间,而后台线程将执行其他一些工作。请在此处查看线程池文档:

我认为这取决于您是否只希望调用该方法之间的X秒延迟为常数,或者是否希望每隔X秒调用一次该方法,但如果该方法的执行时间超过X秒,则有一定的限制


<>您的代码将执行前者,在方法调用之间有一秒的延迟,但是如果您希望每X秒调用一次方法,您可能需要考虑使用“代码> > DATETIME”的时间戳。现在和“代码> DATETIME。减去< /代码>,看看自上次方法调用以来是否已经过了合适的时间。如果系统时钟发生变化,这可能会导致异常行为,例如在夏令时,该方法可能无法运行一小时,但在您的情况下,这种异常行为可能被认为是可以接受的。

他详细说明,他希望“同步”。如果他引入了变为“异步”的多线程——这引入了同步等等。嗨,Michael,感谢您的帮助,并补充了答案:)这个想法与在windows窗体上运行计时器时的行为是一样的:当方法内的代码执行时,一切都会“停止”。类似地,我希望“DoWork”停止所有其他操作(包括计时器),直到它完成,然后再启动计时器。我甚至考虑过使用backgroundworker类在一个单独的线程中启动代码,而且它也可以工作,但是坚持要求(同步执行)我的想法并没有达到目的。嗨,Peter,非常感谢您的回复:)看起来这是最好的方法(根据要求)。。在经过的事件中“停止”计时器,然后再次启动它的整个想法让我有点不安,我认为计时器本身可能有一些属性或方法,我可以使用。我了解到,“SynchronizingObject”属性是在使用System.Windows.Forms.Timer时设置的,但在使用System.Timers.Timer时没有设置,这就是为什么一个异步执行,另一个同步执行(简而言之)?您想使用Stop,因为您不想同时处理两个
已过去的
事件。如果您编写代码来支持这一点,您可以;但是,如果您不编写该代码,则应该使用停止/启动。是的,Windows.Forms.Timer与消息队列一起工作,因此一次只能处理一个勾号(或任何一条消息)。完全同意您的意见:“如果您编写代码来支持此功能,您可以这样做;但是如果您不编写代码,您应该使用停止/启动。”。。我确实使用backgroundworker制作了另一个模型,它实现了相同的功能,但没有坚持同步的要求。我现在就到此为止,在回家的路上——明天我会把你的回答记下来作为答案!非常感谢,伙计。干杯。将你的间歇时间设置为3000而不是1000。那么你就不需要DoWork方法的延迟了。嗨,Kevin,我真的用了额外的2秒钟来模拟一个可能需要一段时间的动作(比如调用某个服务方法或执行一个复杂的存储过程)嗨,MCattle,谢谢你的帮助。。这个想法只是为了确保我不会同时处理两个“已过”事件。执行之间的确切间隔不需要固定,否则我必须完全按照您的建议执行:)