0

I have created a very simple console app which downloads lot of files from web and place them in folder structure following a separate mapping file. The requirement doesn't require that the file needs to downloaded asynchronously.

The program works, but the problem is if somebody chooses to cancel the app using ctrl+c or ctrl+break.

If that is done, the file in progress will become corrupted as the program exit instantly. So I wanted to delete the corrupted file before exiting. So I have written the following handler,

static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
    try
    {
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine("Program interrupted..deleting corrupted file");
        Console.ResetColor();
        if (File.Exists(fileInProgress))
        {
            File.Delete(fileInProgress);
        }
    }
    catch
    {
        Console.WriteLine("Error occured.");
    }
}

fileinprogress is global variable which updated from the function which calls download file.

The problem with above code is if ctrl+c is press it execute the code but it never deletes the file as the file in use. So I followed https://stackoverflow.com/a/937558/714518 and trying to wait untill the program releases the file

static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
    try
    {
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine("Program interrupted..deleting corrupted file");
        Console.ResetColor();
        if (File.Exists(fileInProgress))
        {
            while (IsFileLocked(fileInProgress))
            {
                System.Threading.Thread.Sleep(1000);
            }
            File.Delete(fileInProgress);
        }
    }
    catch
    {
        Console.WriteLine("Error occured.");
    }
}

Now I don't understand the behavior. Now the program waits few seconds if ctrl+c is pressed and then without deleting the file it continues to download the next file. Please help to get rid of this problem.

The actual app is quite larger, I just recreated the situation. Please see http://pastebin.com/TRBEAvwi for full code..

Community
  • 1
  • 1
Web-E
  • 1,169
  • 2
  • 12
  • 17

1 Answers1

0

It sounds like you need a way to signal your download code to stop downloading. From looking at this sample I think the best location would probably be on entry to your Console_CancelKeyPress function. Otherwise your download code will never realize that it needs to release the file lock and stop downloading.

For instance:

static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
    try
    {
        Interlocked.Increment(ref globalStopFlag);

        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine("Program interrupted..deleting corrupted file");
        Console.ResetColor();
        if (File.Exists(fileInProgress))
        {
            while (IsFileLocked(fileInProgress))
            {
                System.Threading.Thread.Sleep(1000);
            }
            File.Delete(fileInProgress);
        }
    }
    catch
    {
        Console.WriteLine("Error occured.");
    }
}

void SomeDownloadFunction()
{
   using (somefile)
   {
     while (!downloadFinished)
    {
        long doINeedToStop = Interlocked.Read(ref   globalStopFlag)

        if (doINeedToStop != 0)
          return;

        //Download the next set of packets and write them to somefile
    }
   }
}
Matt Johnson
  • 1,913
  • 16
  • 23
  • 1
    Your code gives a way to stop the next download. Looks like the file is locked till the downloads complete. In this case, I don't need to delete the file, the download just aborts after current file is downloaded. :) – Web-E Sep 22 '13 at 08:03