做在Windows服务任务循环的最佳方式 [英] Best way to do a task looping in Windows Service

查看:201
本文介绍了做在Windows服务任务循环的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些发短信给我们的客户,如下面的方法:

 公共无效ProccessSmsQueue()
{
   SmsDbContext语境=新SmsDbContext();
   ISmsProvider提供商=新ZenviaProvider();
   SmsManager经理=新SmsManager(背景下,供应商);   尝试
   {
      manager.ProcessQueue();
   }
   赶上(异常前)
   {
      EventLog.WriteEntry(ex.Message,EventLogEntryType.Error);
   }
   最后
   {
      context.Dispose();
   }
}保护覆盖无效的OnStart(字串[] args)
{
   Task.Factory.StartNew(DoWork的).ContinueWith(???)
}

所以,我有一些问题:


  1. 我不知道这需要在方法运行多长时间;


  2. 该方法可以抛出异常,我想在事件日志写


  3. 我要运行循环这种方法,每10分钟,但只有在最后一次执行完成。


我怎样才能做到这一点?我想过使用 ContinueWith(),但我仍然对如何构建整个逻辑的问题。


解决方案

您应该接受一个异步方法的的CancellationToken ,所以它知道何时停止,来电 ProccessSmsQueue 的try-catch 块,并使用 Task.Delay 来异步等待它需要运行,直到下一次:

 公共异步任务DoWorkAsync(令牌的CancellationToken)
{
    而(真)
    {
        尝试
        {
            ProccessSmsQueue();
        }
        赶上(例外五)
        {
            //处理异常
        }
        等待Task.Delay(TimeSpan.FromMinutes(10),令牌);
    }
}

您可以调用此方法,当你的应用程序启动和 Task.Wait 现有因此之前返回的任务,你知道它完成,并没有异常:

 私人任务_proccessSmsQueueTask;
私人CancellationTokenSource _cancellationTokenSource;保护覆盖无效的OnStart(字串[] args)
{
    _cancellationTokenSource =新CancellationTokenSource();
    _proccessSmsQueueTask = Task.Run(()=> DoWorkAsync(_cts.Token));
}保护覆盖无效调用OnStop()
{
    _cancellationTokenSource.Cancel();
    尝试
    {
        _proccessSmsQueueTask.Wait();
    }
    赶上(例外五)
    {
        //手柄exeption
    }
}

I have a method that send some SMS to our customers that look like below:

public void ProccessSmsQueue()
{
   SmsDbContext context = new SmsDbContext();
   ISmsProvider provider = new ZenviaProvider();
   SmsManager manager = new SmsManager(context, provider);

   try
   {
      manager.ProcessQueue();
   }
   catch (Exception ex)
   {
      EventLog.WriteEntry(ex.Message, EventLogEntryType.Error);
   }
   finally
   {
      context.Dispose();
   }
}

protected override void OnStart(string[] args)
{
   Task.Factory.StartNew(DoWork).ContinueWith( ??? )
}

So, I have some issues:

  1. I don´t know how long it takes for the method run;

  2. The method can throw exceptions, that I want to write on EventLog

  3. I want to run this method in loop, every 10 min, but only after last execution finish.

How I can achieve this? I thought about using ContinueWith(), but I still have questions on how to build the entire logic.

解决方案

You should have an async method that accepts a CancellationToken so it knows when to stop, calls ProccessSmsQueue in a try-catch block and uses Task.Delay to asynchronously wait until the next time it needs to run:

public async Task DoWorkAsync(CancellationToken token)
{
    while (true)
    {
        try
        {
            ProccessSmsQueue();
        }
        catch (Exception e)
        {
            // Handle exception
        }
        await Task.Delay(TimeSpan.FromMinutes(10), token);
    }
}

You can call this method when your application starts and Task.Wait the returned task before existing so you know it completes and has no exceptions:

private Task _proccessSmsQueueTask;
private CancellationTokenSource _cancellationTokenSource;

protected override void OnStart(string[] args)
{
    _cancellationTokenSource = new CancellationTokenSource();
    _proccessSmsQueueTask = Task.Run(() => DoWorkAsync(_cts.Token));
}

protected override void OnStop()
{
    _cancellationTokenSource.Cancel();
    try
    {
        _proccessSmsQueueTask.Wait();
    }
    catch (Exception e)
    {
        // handle exeption
    }
}

这篇关于做在Windows服务任务循环的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆