【问题标题】:Get the value of a variable during runtime (Console) [duplicate]在运行时获取变量的值(控制台)[重复]
【发布时间】:2021-05-25 19:35:55
【问题描述】:

我目前正在从事一个涉及控制台应用程序的爱好项目。在我的程序中,我获取数据,对其进行转换,最终将其解析为json。大致的结构是这样的:

static void Main(string[] args)
{
    var sw = new Stopwatch();
    var worker = new Worker();
    var start = DateTime.Now;
    var workSpeed = 0.0;
    Console.WriteLine($"Initialisation started at {start}");
    sw.Start();
    var materials = worker.GatherMaterials();
    var workStart = DateTime.Now;
    Console.WriteLine($"Work started at {workStart}.");
    var products = new List<Product>();
    foreach (var material in materials)
    {
        try
        {
            var product = worker.Process(material);
            products.Add(product);
            sw.Stop();
            workSpeed = (double)products.Count / sw.Elapsed.TotalSeconds;
            sw.Start();   
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            break;
        }
    }
    sw.Stop();
    Console.WriteLine();
    var finish = DateTime.Now;
    Console.WriteLine($"Work finished at {finish}");
    Console.WriteLine($"Ran from {start} to {finish} for approximately {sw.Elapsed} ms.");
    Console.WriteLine($"Processed {products.Count} products for an average processing speed of {workSpeed} products/s.");
    var jsonOptions = new JsonSerializerOptions()
    {
        Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
        WriteIndented = true
    };
    var json = JsonSerializer.Serialize(products, jsonOptions);
    File.WriteAllText("products.json", json, Encoding.UTF8);
    Console.WriteLine("Saved all products to products.json");
}

try 块中有一些代码,我暂时停止秒表以更新处理速度。我这样做是为了可以在那里设置一个断点来检查处理速度。但是,我不想总是在调试模式下运行这个应用程序。理想情况下,我想摆脱我停止和恢复秒表的部分,而是有一种方法可以直接通过控制台与变量进行交互。

例如,是否可以在终端中出现类似Press S to get the current processing speed 的持久性问题,以便在我按下 S 时显示workSpeed 变量的值?

【问题讨论】:

  • 您可以创建另一个线程等待按下 S 并使用 Console.ReadKey 写入 workSpeed 的值。
  • 不确定是谁结束了这个问题,但有两个人提到使用不同的线程,我很想知道是否有人可以提供一个答案来说明这种方法。
  • 在第一个重复链接中,它提供了使用单独线程的示例
  • 昨天发表评论时,我没有时间用代码发布答案。由于问题现在已经结束,这里有一个git gist,其中包含有关如何使用线程执行此操作的代码。
  • 谢谢@SherifElmetainy,我去看看!

标签: c# input console


【解决方案1】:

您可以检查Console.KeyAvailable 的值以查看用户是否按下了某个键(如果按下则为true),然后使用Console.ReadKey(true) 捕获他们按下的键(true 表示不会显示)。

例如:

var sw = new Stopwatch();

Console.WriteLine("Press 'S' to display the elapsed time, 'Q' to quit...");

sw.Start();

while (true)
{
    if (Console.KeyAvailable)
    {
        var input = Console.ReadKey(true).Key;

        if (input == ConsoleKey.S)
        {
            Console.WriteLine($"Elapsed time: {sw.Elapsed.ToString("c")}");
        }
        else if (input == ConsoleKey.Q)
        {
            break;
        }
    }
}

sw.Stop();

Console.WriteLine($"All done. Total elapsed time: {sw.Elapsed.ToString("c")}");
Console.Write("Press any key to exit...");
Console.ReadKey(true);

【讨论】:

  • 所以对于我的代码,我会将KeyAvailable 逻辑放在我的foreach 循环中,对吗?
  • @JansthcirlU 正确,以及循环中的其他代码。这只是检查用户输入的几行代码,如果它是我们关心的值,则向控制台显示一些内容,然后继续循环
  • 感谢您的帮助,如果有机会我会试一试。我可能需要一段时间才能报告结果,只是提个醒。
  • 不着急。最好等一会儿,以防万一有更好的答案出现。 :)
【解决方案2】:

我认为最好的选择是采用多线程方法:将您的实际逻辑保存在单独的线程中,并让主线程处理您感兴趣的查询。请注意,使用多线程方法时,您需要拥有两个线程之间共享资源(并最终进行一些同步),以获得您感兴趣的速率。

【讨论】:

  • 你能提供一个简单的例子吗?
猜你喜欢
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
相关资源
最近更新 更多