12

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

  • The reason you got so many different kinds of replies is that you didn't give a whole lot of information on just what this thing will do. With more info, you'll be able to narrow down some of the options presented so far. – Cheeso Mar 30 '09 at 04:43

11 Answers11

14

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.

ojblass
  • 21,146
  • 22
  • 83
  • 132
  • 2
    Absolutely agreed! Jon Galloway wrote a blog post a while back that convinced me that I was doing it wrong by making a service instead of a task: http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx – Neil Williams Mar 30 '09 at 04:08
  • I think that services offer more flexibility in terms of user credentials. – ojblass Mar 30 '09 at 04:10
  • At least as far as I've seen you can set the credentials that the scheduled task will run under. What can you do with a service that you can't with a task? – Neil Williams Mar 30 '09 at 04:12
  • Bottom line is we don't know because OP didn't tell us what he's actually trying to do. – i_am_jorf Mar 30 '09 at 06:39
8

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

Chris W. Rea
  • 5,430
  • 41
  • 58
5

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();
PhonicUK
  • 13,486
  • 4
  • 43
  • 62
3

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).

noahcoad
  • 101
  • 4
3

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.

i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
  • Hi, Thanks for the update, the reason I selected to do this as a console application is that it then gives me the option of running it manually at any time. The application will read a config file and execute a file read/process at a given time from information stored in the config file. –  Apr 01 '09 at 22:00
  • Will also need to send an alert email if a file is missing from a certian directory. If the file exists it needs to be opened and read looking for errors, any errors then an alert email also needs to be sent. –  Apr 01 '09 at 22:03
2

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.

ojblass
  • 21,146
  • 22
  • 83
  • 132
  • Yes thought a bout a service but don't think it will meet my needs as I need to process files and read configuration information from a stored file to so work at specific times as specified in the configuration file. –  Apr 01 '09 at 22:01
2

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.

Andrew Grant
  • 58,260
  • 22
  • 130
  • 143
1

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.

MichaelGG
  • 9,976
  • 1
  • 39
  • 82
1

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.

Steve Evans
  • 1,118
  • 2
  • 10
  • 16
1

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();

amir
  • 19
  • 1
  • Thread sleep makes the software allot slower and should not be used. You should use AutoResetSignal for a console app or make a service if it needs to run the whole time. – Piotr Kula Jan 28 '15 at 19:24
0

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...");
        }
    }
}
Christian Findlay
  • 6,770
  • 5
  • 51
  • 103