【问题标题】:windows service recursive infinite loop with delayed execution for synchronous taskWindows服务递归无限循环,同步任务延迟执行
【发布时间】:2017-06-01 07:37:45
【问题描述】:

我正在构建一个Windows Service 来从表中读取记录,将记录数据传递给WCF Service,等待它的响应并根据WCF Service 的响应更新数据库中的相同记录。对于所有记录,此过程将继续进行,一旦处理完所有记录,我需要将代码的进一步执行延迟n 分钟数。在n 分钟过去后,我需要调用相同的代码再次从表中读取记录并处理它们,一旦处理完所有记录,再次延迟执行n 分钟数。这需要无限发生,最重要的一点是所有执行都应该发生synchronously,包括延迟执行,我想完全避免使用Threadingasync/await 或任何其他异步编程技术。

搜索while后得知,使用.NET Framework 4.5,推荐的方式是使用Task.Delay()的方法,不使用asycn/await关键字同步添加延迟。所以我创建了一个简单的控制台应用程序,它有一个带有无限循环的recursive 方法:

class Program
    {
        static void Main(string[] args)
        {
            RecursiveMethod();
        }

        public static void RecursiveMethod()
        {
            while (true)
            {
                DoWork();
                Console.WriteLine("Task delayed...");
                Task.Delay(3000).Wait();
                Console.WriteLine("Calling method again recursively...");
                RecursiveMethod();
            }
        }

        public static void DoWork()
        {
            //Do some work
            Console.WriteLine("Work Completed.");
        }
    }

上面的代码似乎工作正常,但我在另一个 Windows 服务中实现System.Timers.Timer 时遇到了大问题,在正常运行两天后,Timer 完全停止工作而没有抛出任何异常,因此没有记录错误这是非常令人沮丧的。

我想避免这种情况,那么为简单的同步代码实现Task.Delay() 的最佳方法是什么?延迟将设置为2 小时,因此我还想处理Task.Delay() 将被垃圾收集或从内存中删除或停止自行工作(不抛出任何异常)并重新启动整个过程的情况。

【问题讨论】:

  • 这将产生堆栈溢出(一段时间后)。
  • @SirRufo 除了我想要达到的目标还有其他选择吗?
  • 是的,阅读一些关于递归的教程来了解为什么你不应该在这里使用它

标签: c# recursion windows-services .net-4.5 delayed-execution


【解决方案1】:

只需使用 Thread.Sleep(3000)。不知道为什么要避免这种情况。您的代码是同步的,因此您不应该使用 Task。

另外,Task.Delay 使用了一个定时器。所以不确定这是否能解决你的问题。

我会尝试找出 Timer 对象停止工作的原因。这听起来不对。

你的定时器回调是否被 try catch 包裹了?

【讨论】:

  • 是的,它被包装在一个 try catch 中,所有错误都记录到数据库中...关于我的问题,对于我想要实现的目标,还有任何其他替代 Thread.Sleep() 的方法吗?
【解决方案2】:

正如其他人所指出的,Task.Delay 在这里不合适,因为您的代码不是异步的。另外,你已经有一个无限循环(while (true)),所以不需要递归:

class Program
{
  static void Main(string[] args)
  {
    while (true)
    {
      DoWork();
      Console.WriteLine("Task delayed...");
      Task.Sleep(3000);
    }
  }

  public static void DoWork()
  {
    //Do some work
    Console.WriteLine("Work Completed.");
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2015-01-27
    相关资源
    最近更新 更多