【问题标题】:.NET Console application. Way to cancel infinite loop with long blocking operation.NET 控制台应用程序。用长阻塞操作取消无限循环的方法
【发布时间】:2014-09-13 13:44:44
【问题描述】:

我正在创建一个小型应用程序,用于检测系统上的一些变化。它由管理员使用,因此它不必漂亮和“完美”。

我有循环检查更改。我想每 10 秒检查一次更改。但我希望能够通过按下按钮“取消”那个 thread.sleep 以退出该循环。

    static async void Main(string[] args)
    {
        Console.WriteLine("Logger started. Press any key to exit application.\n");

        while (!Console.KeyAvailable) //Works. but only every 10 seconds
        {
            CheckForAndLogChanges();
            Thread.Sleep(10000);
        }

        //Rest of code that I want to execute right after pressing key without waiting 10s.

    }

更新: 我喜欢用计时器回答。

这也是我想出来的:

    static void Main(string[] args)
    {
        Console.WriteLine("Logger started. Press any key to exit application.\n");

        var backgroutTask = new Task(WorkerThread, TaskCreationOptions.LongRunning);
        backgroutTask.Start();

        Console.ReadKey(false);
    }

    static async void WorkerThread()
    {
        while (true)
        {
            CheckForAndLogChanges();
            await Task.Delay(100);
        }
    }

在这个任务上使用计时器有什么好处?

【问题讨论】:

  • 这很简单,只需休眠 100 毫秒并在 CheckForAndLogChanges() 之前数到 100。毕竟它不必完美。
  • @HansPassant 为了学习,我希望这个微不足道的程序尽可能完美。我想写出好的代码。即使是那些简单的任务。
  • 琐碎的代码就是好代码,它的错误少得多,维护起来也容易得多。如果您想了解 Timer 可以让您的生活变得悲惨的众多方式,并且它与您可能找到的框架一样悲惨,那么您肯定不需要我们的帮助。
  • @HansPassant 我理解你的观点。只是那个简单的程序不会被维护或广泛使用。它只是一个小工具,更适合我检查新事物并学习一点.net。我知道并不总是需要编写“完美”的代码。但我只是想尝试一下。如果我今天学会了。我将来会在更大的应用程序中使用它。
  • @Hooch 我删除了我的答案。我相信Timer 在这种情况下可能会很好。但是有不同的计时器,参见例如stackoverflow.com/q/1416803(还有更多)。有不同的方式与主线程同步,也有不同的方式来等待可能的运行操作终止。我没有时间相应地扩展答案,只是不想半途而废,因为它可能会误导某人。

标签: c# .net loops console


【解决方案1】:

使用ManualResetEvent

ManualResetEvent mre=new ManualResetEvent(false);
//......
var signalled=mre.WaitOne(TimeSpan.FromSeconds(8));
if(!signalled)
{
    //timeout occurred
}

其他地方(在 8 秒结束之前):

mre.Set(); //unfreezes paused Thread and causes signalled==true

并允许未阻塞的线程优雅地终止。 Thread.Abortevil and should be avoided

【讨论】:

  • 以上所有。我认为计时器或任务将是更好的选择。您的代码正在运行,但 ManualResetEvent 对我想要做的事情来说不是有点矫枉过正吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
相关资源
最近更新 更多