【问题标题】:Building Windows Service in C# with periodic task [duplicate]使用定期任务在 C# 中构建 Windows 服务 [重复]
【发布时间】:2021-02-08 13:50:30
【问题描述】:

我想用 C# 构建一个 Windows 服务。

此服务需要每隔 10 秒定期运行一次。

问题:

  1. Timers.timer 和 Threading.timer 有什么区别?

  2. 如何调用带参数的 CheckingThings?

  3. 如果我运行此代码,它会像此处声明的那样每秒多次调用 CheckingThings:

_timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);

这是我目前得到的:

public partial class WindowsService1 : ServiceBase
{

    // Logging
    private static Serilog.Core.Logger _logEvent;


    public WindowsService1()
    {
        InitializeComponent();
    }

    public void OnDebug() {
        OnStart(null);
    }


    protected override void OnStart(string[] args)
    {

        //Logging
        try {
            _logEvent = new LoggerConfiguration()
                .WriteTo.File(AppDomain.CurrentDomain.BaseDirectory + @"Logs\Logfile.txt", rollingInterval: RollingInterval.Month)
                .CreateLogger();
        }
        catch (Exception e)
        {
            _logEvent.Error("The logging service is not working as expected: {errorMsg}", e);
        }

        try
        {
        // initializing some data here

                var autoEvent = new AutoResetEvent(true);
                while (true)
                {
                    _timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
                }
        }
        catch (Exception e) {
            _logEvent.Error("An error occured while initializing service: {0}", e);
        }
    }

    private static void CheckingThings(object stateInfo) 
        AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;

    //These things needs to run periodically every 10s
    }

    protected override void OnStop()
    {
        _logEvent.Information("Stopping  Service ...");
    }

}

【问题讨论】:

  • 您的第一个问题已经在这里得到解答:stackoverflow.com/questions/1416803/…
  • 你似乎创建了无限数量的计时器while (true) _timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
  • 如果我删除 while 循环它只运行一次
  • 您想构建 Windows 服务还是定期运行它
  • 我如何使用参数调用 CheckingThings? - 如果您对计时器说“这里,每 10 秒调用一次此方法并提供各种参数”,您如何期待计时器知道要提供哪些参数?您如何期望手机的早上 8 点闹钟会打开您的咖啡机?您希望它如何拨入您上午 10 点会议的会议号码和 PIN 码? (提示;它不会 - 它只是提醒您当前时间,因此您必须执行这些操作)

标签: c# multithreading service task


【解决方案1】:

这是一个每分钟执行一些操作的服务类的框架,使用 System.Timers.Timer

public partial class XService : ServiceBase
{
    private Timer _minute = new Timer(60000);

    public XService()
    {
        InitializeComponent();

        _minute.Elapsed += Minute_Elapsed;
    }

    //this is async because my 'stuff' is async
    private async void Minute_Elapsed(object sender, ElapsedEventArgs e)
    {
        _minute.Stop();
        try
        {
            //stuff
        }
        catch (Exception ex)
        {
            //log ?
        }
        finally
        {
            _minute.Start();
        }
    }

    protected override void OnStart(string[] args)
    {
        _minute.Start();            //this or..

        Minute_Elapsed(null, null); //..this, if you want to do the things as soon as the service starts (otherwise the first tick will be a minute after start is called
    }

 ...

我通常会在我做我的事情时停止我的计时器 - 开始一项需要 10 分钟然后一分钟后再做一次的工作是没有意义的,因此停止/尝试/最终/开始模式

编辑:

这是课程的结尾部分,以及它是如何在调试(在 Visual Studio 内部)和发布(作为已安装的 Windows 服务)中启动/启动的:

        //just an adapter method so we can call OnStart like the service manager does, in a debugging context
        public void PubOnStop()
        {
            OnStop();
        }
    }// end of XService class
        static void Main(string[] args)
        {
#if DEBUG
            new XService().PubStart(args);
            Thread.Sleep(Timeout.Infinite);
#else

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[]
            {
                new XService()
            };
            ServiceBase.Run(ServicesToRun);
#endif
        }

【讨论】:

  • 非常感谢!!!如果我必须从 text/ini 文件中读取要检查的内容怎么办?有可能通过那些吗?
  • Minute_Elapsed 中的代码实际上没有任何限制。好吧,除非您以无权访问本地磁盘资源的用户身份运行该服务...阅读您的 INI如果您不想停止并重新启动获取新设置的服务
  • 我试过你的骨架,但它没有做循环计时器?!
  • 呃.. 我直接将它从一个工作服务中提取出来,该服务每分钟都会检查它必须编码的视频。你是如何开始服务的?
  • 这就是我启动服务的方式 backgroundTask = Task.Factory.StartNew(() => CheckingThings(cancellation), canceling, TaskCreationOptions.LongRunning, TaskScheduler.Default);背景任务.Wait(); while (!cancellation.IsCancellationRequested) { // 主线程需要在那里工作 }
猜你喜欢
  • 1970-01-01
  • 2013-04-09
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多