0

In my program I approaching text files in every iteration of loop to not lost any data from running. It is brutal uneffective and still I lost that data yesterday.

I have 2 Queues - "what have I done" and "what to do". After some time I need to end this application and remember these queues for next app run. I usually kill the applicatiaon with Ctrl+C.

Is there any way to run saving these Queues to files after app kill? Or how to End console application as a User correctly.

Is it possible to run piece of code atomically? I mean when I update some "Queue file" by removing first line of it I need to copy whole file to tmp than delete original file and than copy tmp file to original. But sometimes I hit Ctrl+C right after orig. file delete and I lost one queue.

Soner Gönül
  • 91,172
  • 101
  • 184
  • 324
Gondil
  • 727
  • 1
  • 9
  • 22
  • first: don't *kill* your program - use some kind of user-interaction (a simple text-based menu will do) and exit it in a save manner - then why don't you just add the line first to *done* and remove it then from *todo* - you don't have to copy files around and even if you fail in between you see matching entries and know that you have to remove the *todo* part ... the alternative of course is to just flag your entries as *done* instead... – Carsten Oct 21 '15 at 06:16
  • @Carsten my program does not interact with user at all it is just crawling web. Seems that this answer solved my problem: http://stackoverflow.com/a/22996661 – Gondil Oct 21 '15 at 06:19

3 Answers3

2

Ctrl+C doesn't necessarily kill the application - you can use the Console.CancelKeyPress event to handle the shutdown properly. As for when the user clicks the close button, you're out of luck - that actually does brutally kill the process.

Your application should have some support for a graceful shutdown. For example, you could have a cancellation token that's signalled in the Console.CancelKeyPress, and your code should check the token once in a while (when you're in a spot that's safe for termination) to see if a shutdown was requested.

As an extra measure, you could try using some safer measure of operation. For example, instead of deleting the original file, you could just rename it. If your processing fails in the middle, the file is still there, and you can recover it when the application is restarted. Only when a new file is completely processed and copied would you delete the original.

Luaan
  • 57,516
  • 7
  • 84
  • 100
1

Is there any way to run saving these Queues to files after app kill?

No. You must implement exit command.

Here is the solution.

Mariusz
  • 442
  • 5
  • 16
0

It looks like you can hook into the CTRL-C or CTRL-BREAK Signals in order to exit your application gracefully.

class Program
{
    //https://msdn.microsoft.com/en-us/library/windows/desktop/ms683231(v=vs.85).aspx
    private const int STD_INPUT_HANDLE = -10;
    private const uint ENABLE_PROCESSED_INPUT = 0x0001;


    [DllImport("Kernel32.dll")]
    private static extern IntPtr GetStdHandle(int nStdHandle);

    [DllImport("Kernel32.dll")]
    private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

    [DllImport("Kernel32.dll")]
    private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint dwMode);

    static void Main(string[] args)
    {
        IntPtr handle = GetStdHandle(STD_INPUT_HANDLE);

        uint mode;
        GetConsoleMode(handle, out mode);
        mode &= ~ENABLE_PROCESSED_INPUT;

        SetConsoleMode(handle, mode);

        new Thread(() =>
        {
            while (true)
            {
                var chara = Console.ReadKey();

                if (chara.KeyChar == 3)
                {
                    Console.WriteLine("ctrl-c");
                    //signal to gracefully exit
                }

                Console.WriteLine("c:{0}", chara);
            }

        }).Start();
    }
}
Geoff
  • 99
  • 5