0

詳細に入る前に、私のプログラムは C# .Net 4.0 を使用して Visual Studio 2010 で作成されています。

実行ごとに個別のログ ファイルを生成するプログラムを作成しました。ログ ファイルの名前は時間にちなんで付けられ、ミリ秒単位まで正確です (たとえば、20130726103042375.log )。プログラムは、その日のマスター ログ ファイルが存在しない場合は、それも生成します (たとえば、*20130726_Master.log*)。

各実行の最後に、ログ ファイルをマスター ログ ファイルに追加したいと考えています。正常に追加できるかどうかを確認する方法はありますか? そしてSleep、1秒か何か後に再試行しますか?

基本的に、1 つの実行可能ファイルと複数のユーザー (5 人のユーザーがいるとしましょう) があります。

5 人のユーザー全員が同時にこの実行可能ファイルにアクセスして実行します。すべてのユーザーがまったく同じ時間 (ミリ秒まで) に開始することはほぼ不可能であるため、個々のログ ファイルを生成しても問題はありません。

ただし、これらのログ ファイルをマスター ログ ファイルにマージしようとすると、問題が発生します。可能性は低いですが、複数のユーザーが同じマスター ログ ファイルに追加すると、プログラムがクラッシュすると思います。

私が使用する方法は

File.AppendAllText(masterLogFile, File.ReadAllText(individualLogFile));

オブジェクトにチェックインしましたlockが、1 つのインスタンスで複数のスレッドではなく複数のインスタンスが実行されているため、私の場合は機能しないと思います。

私が調べる別の方法はtry/catch、このようなものです

try
{
    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch {}

しかし、masterLogFile のステータスはその短いミリ秒で変化する可能性があるため、これで問題が解決するとは思いません。

したがって、私の全体的な質問は次のとおりです。masterLogFile が使用されていない場合に追加し、使用されている場合は短いタイムアウト後に再試行する方法はありますか? または、masterLogFile を作成する別の方法がある場合は?

よろしくお願いします。長いメッセージで申し訳ありません。誰の時間も無駄にしないように、自分のメッセージを確実に伝え、自分が試したことや調査したことを説明したいと思います。

あなたを助けるために私が提供できる情報が他にある場合はお知らせください。

4

2 に答える 2

0

オーバーヘッドが最も少ないと思うので、これに沿って何かをします。例外がスローされた場合、Try/catch はスタック トレースを生成します (これには 1 秒かかる場合があります)。これをアトミックに行うためのより良い方法が必要です。見つけたら投稿します。

于 2013-07-26T16:17:41.897 に答える
0

あなたのtry / catchは物事を行う方法です。への呼び出しがFile.Open成功すると、ファイルに書き込むことができます。アイデアは、ファイルを開いたままにすることです。私は次のようなものを提案します:

bool openSuccessful = false;
while (!openSuccessful)
{
    try
    {
        using (var writer = new StreamWriter(masterlog, true)) // append
        {
            // successfully opened file
            openSuccessful = true;
            try
            {
                foreach (var line in File.ReadLines(individualLogFile))
                {
                    writer.WriteLine(line);
                }
            }
            catch (exceptions that occur while writing)
            {
                // something unexpected happened.
                // handle the error and exit the loop.
                break;
            }
        }
    }
    catch (exceptions that occur when trying to open the file)
    {
        // couldn't open the file.
        // If the exception is because it's opened in another process,
        // then delay and retry.
        // Otherwise exit.
        Sleep(1000);
    }
}
if (!openSuccessful)
{
    // notify of error
}

そのため、ファイルを開くことができなかった場合は、スリープしてからもう一度やり直してください。

もう少し詳細については、私のブログ投稿File.Exists is only a snapshotを参照してください。

于 2013-07-26T16:00:47.197 に答える