对于C#控制台应用程序中的长时间运行进程,我有哪些选项?

时间:2021-08-07 19:34:25

I'm working on a console app that kicks off a fairly long running process (2-3 minutes). What options are available for displaying progress, or even just writing a "." to screen every few seconds so the user knows the app hasn't stopped responding? I'm a newbie to desktop development, so bear with me. Thanks!

我正在开发一个控制台应用程序,开启一个相当长的运行过程(2-3分钟)。有哪些选项可用于显示进度,甚至只是写一个“。”每隔几秒进行一次屏幕,以便用户知道应用程序没有停止响应?我是桌面开发的新手,所以请耐心等待。谢谢!

2 个解决方案

#1


1  

You have (at least) 3 ways to do this:

你有(至少)3种方法来做到这一点:

  • Simplest: On program start, set a global variable to false, then start a thread that writes a dot to the console, Thread.Sleep()s a second, repeats until the variable is set to true. On your main thread do your work, when finished set the variable to true and then Join() the other thread.
  • 最简单:在程序启动时,将全局变量设置为false,然后启动一个将点写入控制台的线程,Thread.Sleep()s一秒钟,重复直到该变量设置为true。在你的主线程上做你的工作,完成后将变量设置为true,然后加入()另一个线程。

  • Still simple: Add another global variable to the mix, type int. In your worker thread increase it, whenever some progress is made, on the console writer thread reduce interval to say 250ms, but draw a dot only if progress counter has changed. This gives an idea of how fast your app progresses
  • 还是很简单:在mix中添加另一个全局变量,输入int。在你的工作线程中增加它,无论何时取得一些进展,在控制台编写器线程减少间隔为250毫秒,但只有在进度计数器已更改时才绘制一个点。这可以让您了解应用程序的进展速度

  • A bit advanced: Create a boolean as in first step plus an AutoResetEvent, let the console writer thread repeatedly wait on the event, when app makes progress Set() the event. When finished set boolean to true and Set() again before Join()ing. The advanced part in this is to know, in what portions to report progress.
  • 有点高级:在第一步创建一个布尔加上一个AutoResetEvent,让控制器编写器线程重复等待事件,当app进行进度时Set()事件。完成后,在Join()之前将boolean设置为true并再次设置Set()。这方面的高级部分是知道报告进展的部分。

#2


0  

The simplest approach is if your application has an incremental loop then you could put a simple full stop on the the console. Not nice, but it does give an indication of "I'm alive".

最简单的方法是,如果您的应用程序具有增量循环,那么您可以在控制台上放置一个简单的句点。不好,但它确实表明“我还活着”。

But that approach can result in too much info (too many characters going to console) or too few as your hooking into a bit of the code that does not really have that responsibility.

但是这种方法可能会导致过多的信息(太多的字符转到控制台)或者太少,因为你会陷入一些没有真正负责的代码。

So, perhaps a nicer way that you can reuse is to create a console user class that is run in a thread with a 1 second tick. It can use backspacing and the good old | / | / - sequence to give the impression of something rotating. It can also check for key presses to allow the user to exit.

因此,您可以重用的一种更好的方法是创建一个控制台用户类,该用户类在1秒钟内的线程中运行。它可以使用退格和好旧| / | / - 序列给人一种旋转的印象。它还可以检查按键以允许用户退出。

Another option, depending on the nature of your users, is to use a logging framework like NLog. That way your implementation is UI independent and you can see what is happening in more or less detail at run time in the console, from another machine, whatever.

根据用户的性质,另一个选择是使用像NLog这样的日志框架。这样,您的实现是独立于UI的,您可以在运行时在控制台中,从另一台计算机上查看或多或少的详细信息。

#1


1  

You have (at least) 3 ways to do this:

你有(至少)3种方法来做到这一点:

  • Simplest: On program start, set a global variable to false, then start a thread that writes a dot to the console, Thread.Sleep()s a second, repeats until the variable is set to true. On your main thread do your work, when finished set the variable to true and then Join() the other thread.
  • 最简单:在程序启动时,将全局变量设置为false,然后启动一个将点写入控制台的线程,Thread.Sleep()s一秒钟,重复直到该变量设置为true。在你的主线程上做你的工作,完成后将变量设置为true,然后加入()另一个线程。

  • Still simple: Add another global variable to the mix, type int. In your worker thread increase it, whenever some progress is made, on the console writer thread reduce interval to say 250ms, but draw a dot only if progress counter has changed. This gives an idea of how fast your app progresses
  • 还是很简单:在mix中添加另一个全局变量,输入int。在你的工作线程中增加它,无论何时取得一些进展,在控制台编写器线程减少间隔为250毫秒,但只有在进度计数器已更改时才绘制一个点。这可以让您了解应用程序的进展速度

  • A bit advanced: Create a boolean as in first step plus an AutoResetEvent, let the console writer thread repeatedly wait on the event, when app makes progress Set() the event. When finished set boolean to true and Set() again before Join()ing. The advanced part in this is to know, in what portions to report progress.
  • 有点高级:在第一步创建一个布尔加上一个AutoResetEvent,让控制器编写器线程重复等待事件,当app进行进度时Set()事件。完成后,在Join()之前将boolean设置为true并再次设置Set()。这方面的高级部分是知道报告进展的部分。

#2


0  

The simplest approach is if your application has an incremental loop then you could put a simple full stop on the the console. Not nice, but it does give an indication of "I'm alive".

最简单的方法是,如果您的应用程序具有增量循环,那么您可以在控制台上放置一个简单的句点。不好,但它确实表明“我还活着”。

But that approach can result in too much info (too many characters going to console) or too few as your hooking into a bit of the code that does not really have that responsibility.

但是这种方法可能会导致过多的信息(太多的字符转到控制台)或者太少,因为你会陷入一些没有真正负责的代码。

So, perhaps a nicer way that you can reuse is to create a console user class that is run in a thread with a 1 second tick. It can use backspacing and the good old | / | / - sequence to give the impression of something rotating. It can also check for key presses to allow the user to exit.

因此,您可以重用的一种更好的方法是创建一个控制台用户类,该用户类在1秒钟内的线程中运行。它可以使用退格和好旧| / | / - 序列给人一种旋转的印象。它还可以检查按键以允许用户退出。

Another option, depending on the nature of your users, is to use a logging framework like NLog. That way your implementation is UI independent and you can see what is happening in more or less detail at run time in the console, from another machine, whatever.

根据用户的性质,另一个选择是使用像NLog这样的日志框架。这样,您的实现是独立于UI的,您可以在运行时在控制台中,从另一台计算机上查看或多或少的详细信息。