0

Web から多くのファイルをダウンロードし、別のマッピング ファイルに従ってフォルダー構造に配置する非常に単純なコンソール アプリを作成しました。この要件では、ファイルを非同期でダウンロードする必要はありません。

プログラムは機能しますが、問題は、誰かが ctrl+c または ctrl+break を使用してアプリをキャンセルすることを選択した場合です。

それが行われると、プログラムが即座に終了するため、進行中のファイルが破損します。そのため、終了する前に破損したファイルを削除したかったのです。したがって、次のハンドラーを作成しました。

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ダウンロードファイルを呼び出す関数から更新されたグローバル変数です。

上記のコードの問題は、ctrl+c を押してコードを実行すると、使用中のファイルとしてファイルが削除されないことです。だから私はhttps://stackoverflow.com/a/937558/714518に従い、プログラムがファイルを解放するまで待機しようとしました

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.");
    }
}

今、私は行動を理解していません。ctrl+c が押された場合、プログラムは数秒待機し、ファイルを削除せずに次のファイルのダウンロードを続行します。この問題を取り除くのを手伝ってください。

実際のアプリはかなり大きく、状況を再現しただけです。完全なコードについては、 http://pastebin.com/TRBEAvwiを参照してください。

4

1 に答える 1

0

ダウンロードコードにダウンロードを停止するよう通知する方法が必要なようです。このサンプルを見ると、最適な場所はおそらく Console_CancelKeyPress 関数の入り口になると思います。そうしないと、ダウンロード コードは、ファイル ロックを解除してダウンロードを停止する必要があることを決して認識しません。

例えば:

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
    }
   }
}
于 2013-09-22T06:44:24.717 に答える