【问题标题】:how to check stdin in C# while doing something如何在做某事时检查 C# 中的标准输入
【发布时间】:2023-03-31 01:44:01
【问题描述】:

我有一个这样的程序:

Class a
{
    main()
    {
        while(abc)
        {
            f(a);
            g(b);
        }
    }
}

但我需要检查标准输入是否有一些重要的命令。如果我收到来自标准输入的命令,该程序应该可以工作。在命令之后,我应该决定继续执行或做其他事情。 我该怎么办?

【问题讨论】:

  • 听起来你在说程序已经在运行(而不是启动),你需要在它运行时接受用户的命令。这是正确的吗?如果是这样:您的程序是否暂停以接受来自控制台的输入以允许用户输入命令,或者您的程序是否作为 Windows 服务运行,是否运行多个线程,或者是不同的场景?
  • 是的,它正在运行。但是打开两个线程会破坏我的程序我需要中断之类的东西。我需要我的 CPU 时间,所以像两个线程这样的东西会破坏我正在运行的程序
  • 销毁你的程序是什么意思?有时,当你需要你的代码做一些它目前不能做的事情时,你可能不得不改变你以前写的很多代码!
  • 低优先级线程不会“破坏你正在运行的程序”,并且足够快,可以让人类用户与之交互。线程不会破坏您的程序,并且如果计算机上正在运行任何其他进程(并且有),它们也在使用您的 CPU。不过有趣的场景。
  • 我知道。在我的程序中使用最大 cpu 时间非常重要。所以我需要一个类似中断的东西。

标签: c# concurrency stdin


【解决方案1】:

在不同的线程中执行 fg 并访问某种变量以传播状态变化。

Class Program
{
  public static void Main()
  {
    ThreadPool.QueueUserWorkItem(() => f(a));
    ThreadPool.QueueUserWorkItem(() => g(b));

    while(true)
    {
      if(Console.Readline() == "something")
        //do something
    }
  }

  private static void f (param)
  {
    while(abc)
      //do work
  }
}

【讨论】:

  • 使用线程之类的东西会占用大量 CPU 时间。我需要所有的 CPU 时间来运行我的功能。我认为像中断这样的东西会起作用..但我不知道怎么做?
  • CPU 时间是调度器的问题,而不是你的问题。你可以设置一个ThreadPriorty,你知道吗? msdn.microsoft.com/en-us/library/…
  • @Masoud:线程不会增加很多开销。我无法想象你正在做的事情实际上需要如此多的 CPU 时间,以至于线程开销太高,但你不了解线程、中断等是如何工作的。
  • @Masoud - 主线程实际上将被阻塞,直到用户在 ReadLine() 方法中按下 ENTER。一个易失的布尔值可以用来表示执行结束。将这两件事放在一起,可以肯定的是,这种方法的线程开销应该完全可以忽略不计。
【解决方案2】:

如果您的命令是单个字符,这将起作用。

Class a
{
    main()
    {
        bool done = false;
        Console.CancelKeyPress += (s, e) => { done = true; e.Cancel = true; };
        while(!done)
        {
            f(a);
            g(b);
            if (Console.KeyAvailable)
            {
                switch(Console.ReadKey().KeyChar)
                {
                    case 'i':
                    case 'I':
                        DoSomethingImportant();
                        break;
                    case 'E':
                    case 'e':
                        done = true;
                        break;
                }
            }
        }
    }
}

如果命令长于单个字符,则可以将键存储在缓冲区中,并在每次击键时查找已完成的命令。

还有其他更复杂的涉及线程的解决方案,但如果您不需要朝那个方向发展,那么您不应该这样做。

(我在上面的代码中添加了CTRL-C处理,所以如果用户试图停止程序,它会干净地退出。这部分是可选的。)

【讨论】:

    【解决方案3】:

    据我了解,您需要在 while 循环之前启动另一个线程,它可以从标准输入中获取命令。

    【讨论】:

    • 我不能使用线程。因为我需要我的 CPU 时间。我需要中断之类的东西。
    • @Masoud 第二个线程将消耗可以忽略不计的 CPU 时间。尤其是当您等待输入时,线程实际上会等待中断而不消耗 CPU 时间。
    猜你喜欢
    • 2011-04-27
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 2019-11-15
    • 2013-02-14
    • 2015-10-09
    • 2020-11-24
    相关资源
    最近更新 更多