C# Console Application - Keep it running

2019-01-23 15:45发布

问题:

I am about to develop a console application that will be required to continually run and carry out work at specific times.

My question is what is are best methods or practices to keep your application alive?

My thought were: A loop that never ends? A timer that sleeps and then jumps to routine when required (after set sleep period)?

I will be compiling the application into an exe and then running it as a service using AlwaysUp.

Regards..

Peter

回答1:

A better solution would be to write a console application that does its job and quits. You can then use the Windows Task Scheduler to run it periodically.



回答2:

Why don't you build your app as a service in the first place?



回答3:

While you should really be using a service for this, if you need/want to do this anyway, you can use a ManualResetEvent to do this:

private ManualResetEvent Wait = new ManualResetEvent(false);

When you're finished 'starting' and want to just wait, you'd then do:

Wait.WaitOne();

When you want to stop and let it exit, you can then do:

Wait.Set();


回答4:

You probably don't want to just spin in a loop needlessly consuming processor time.

Assuming you are on windows, you should have a loop that never ends with a call to WaitForSingleObject() or WaitForMultipleObjects() or MsgWaitForMultipleObjects() depending on your needs. Then have some synchronization object that wakes you up, such as a named event.

See the Win32 Synchronization documentation here. If you elaborate more on what your program needs to do, we can probably provide more specific advice.



回答5:

You can add a reference to System.Windows.Forms and call System.Windows.Forms.Application.Run() to begin a standard application message loop. Ctrl-C will terminate the app.

Another option is to use Console.ReadKey() to pause the app. Like Console.WriteLine("Press [ANY] key to quit..."); Console.ReadKey();

That's what I use in my console apps when they're just sitting there waiting for events to occur. In either case the app will continue to run and catch triggered events (like from a timer, WCF, FileWatcher, etc).



回答6:

Code that runs continually is called a daemon and there is an article here outlining how to do what you ask. That will point you to an example of how to write a simple service here.



回答7:

If your program is going to be continually running then you should sleep until the desired event occurs (e.g. XX seconds passes). If you just spin in a while {} loop you'll suck up CPU times.

If your program is going to always be running on a machine then you should consider making it a service so it automatically starts and stops with the machine.



回答8:

Well I'm sure at some point it should stop, no?

Spawn a thread that does work, and have the main thread block on Console.ReadLine() if you want it to be runnable as a console app too.

If you really just want to pause the main thread forever, just block on a ManualResetEvent you never fire.

But, consider using a service if you can.



回答9:

If your building a desktop application you'll want to have it run in the system tray. This will

  1. Keep your users from accidentally closing the application
  2. Keep your application from cluttering the screen of your users

If your building a server application you will want to write a windows service. This will

  1. Keep an administrator from accidentally closing your application
  2. Eliminate the need for the server to have someone logged into the console for your application to be running in

As someone who is primarily an IT Pro I would say that 3rd party applications that we get that run as console apps instead of windows services we put a lot of effort into keeping from being purchased. It creates a lot of work for us, and opens up significant support issues and security holes.



回答10:

Sending a thread to sleep: System.Threading.Thread.Sleep(10000);

Waiting for a key to be pressed: Console.WriteLine("Press any key to continue..."); Console.Read();



回答11:

Create a Task and then Wait it.

class Program
{
    static void Main(string[] args)
    {
        var processTask = Process();
        processTask.Wait();
    }

    private static async Task Process()
    {
        var isNotCancelled = true;

        while (isNotCancelled)
        {
            //Polling time here
            await Task.Delay(1000);

            //TODO: Do work here and listen for cancel
            Console.WriteLine("I did  some work...");
        }
    }
}