在.Net.Timer启动后阻止我的控制台应用程序关闭

时间:2014-01-24 18:48:38

标签: c#

所以我有这个简单的代码:

static void Main(string[] args)
  {
      var timer = new Timer(0.5 * 60 * 1000); // 0.5 minutes times 60 seconds times 1000 miliseconds
      timer.Elapsed += new System.Timers.ElapsedEventHandler(Start);
      timer.AutoReset = true;            
      timer.Start();
  }

启动一个启动整个程序逻辑的计时器。问题是,控制台应用程序关闭,什么也没做。我该如何防止这种情况?我知道,如果我做了类似的事情(真实),它可以工作,但这似乎不是一个优雅/适当的解决方案。

5 个答案:

答案 0 :(得分:7)

也许试试

Console.Read(); 

代码末尾

由于这个原因,只要用户不按某个键,您的控制台窗口就不会关闭。

答案 1 :(得分:3)

最后一个答案是 7 岁。与此同时,来自 System.Threading 的方法,如 Timer、Sleep、... 不应再使用。它们存在死锁风险,我必须警告不要使用它们,尤其是在 ASP.NET Core 中。

有几件事情需要考虑:

  • 没有程序永远运行。当程序应该关闭(通过关闭或信号)时会发生什么?
  • 必须在您的程序逻辑中实现终止。许多异步 .NET Core 方法支持 CancellationToken 作为参数。

有两种方法可以创建一个“无止境”的程序:

  • .NET Core 中的 Worker 服务是当今编写应作为服务永久运行的程序的常用方法。它们可以注册为 Windows 服务。 如果您想将您的服务注册为“真正的”服务,请参阅有关 link to Qt archivesdocs.microsoft.com 的更多信息。
  • 如果您需要一个在前台执行任务的“真实”控制台应用程序,可以使用以下示例代码来完成:
using System;
using System.Threading.Tasks;
using System.Threading;

namespace DemoApp
{
    internal class Program
    {
        private static int _isRunning = 0;

        private static async Task Main(string[] args)
        {
            // No program can run infinitely. We always have to provide a mechanism for termination.
            var tcs = new CancellationTokenSource();
            var periodTimeSpan = TimeSpan.FromSeconds(10);

            // This mechanism is CTRL+C, so we catch this.
            Console.CancelKeyPress += (sender, e) =>
            {
                tcs.Cancel();
                e.Cancel = true;
            };

            try
            {
                // No endless loop. We are checking for a cancellation request!
                while (!tcs.IsCancellationRequested)
                {
                    // Perform your work.
                    var task1 = Run(tcs.Token);
                    var task2 = Task.Delay(periodTimeSpan, tcs.Token);
                    // If the execution time of Run is greater than periodTimeSpan, we will wait. Depends on your needs.
                    await Task.WhenAll(task1, task2);
                }
            }
            catch (TaskCanceledException)
            {
                Console.WriteLine("User canceled your app.");
            }
        }

        private static async Task Run(CancellationToken token)
        {
            // Should never occur if you use WhenAll()
            if (Interlocked.Exchange(ref _isRunning, 1) == 0)
            {
                // Perform your work.
                _isRunning = 0;
            }
        }
    }
}

答案 2 :(得分:1)

添加Console.ReadKey();这将允许您通过按任意键关闭控制台窗口。

    static void Main(string[] args)
    {
        var timer = new Timer(0.5 * 60 * 1000); // 0.5 minutes times 60 seconds times 1000 miliseconds
        timer.Elapsed += new System.Timers.ElapsedEventHandler(Start);
        timer.AutoReset = true;            
        timer.Start();

        Console.ReadKey();
    }

答案 3 :(得分:1)

如果您只想运行计时器并等待,那么Console.Read()就是您的朋友。

您的代码终止的原因是因为该函数初始化计时器,启动它然后...命中Main函数的结尾。结果,该功能退出。

当前代码没有做任何有用的事情(除了启动被忽略的计时器)。

如果您想查看计时器的运行情况,请在启动计时器后执行其他操作。然后,在一段时间后停止计时器并打印/评估它你认为合适的方式。 (计时器不在主线程上运行,而Console.Read()之类的东西将在主线程上,因此阻塞线程直到你输入)

答案 4 :(得分:0)

您的控制台应用程序未因计时器启动而结束。它结束是因为程序到达Main()方法的末尾。

无论您采取什么措施来阻止程序退出Main()都会有所帮助。虽然许多提出的解决方我想突出一个事实,即它不是导致问题的计时器。