どのレポートを生成する必要があるかを判断するためにテキスト ファイルから読み取るアプリがあります。ほとんどの場合は正常に動作しますが、時々、プログラムが読み書きするテキスト ファイルの 1 つを削除することがあります。その後、例外がスローされ (「ファイルが見つかりませんでした」)、進行が停止します。
ここにいくつかの関連コードがあります。
まず、ファイルから読み取ります。
List<String> delPerfRecords = ReadFileContents(DelPerfFile);
. . .
private static List<String> ReadFileContents(string fileName)
{
List<String> fileContents = new List<string>();
try
{
fileContents = File.ReadAllLines(fileName).ToList();
}
catch (Exception ex)
{
RoboReporterConstsAndUtils.HandleException(ex);
}
return fileContents;
}
次に、ファイルに書き込みます。そのファイルのレコード/行を処理済みとしてマークし、次にファイルを調べたときに同じレポートが再生成されないようにします。
MarkAsProcessed(DelPerfFile, qrRecord);
. . .
private static void MarkAsProcessed(string fileToUpdate, string
qrRecord)
{
try
{
var fileContents = File.ReadAllLines(fileToUpdate).ToList();
for (int i = 0; i < fileContents.Count; i++)
{
if (fileContents[i] == qrRecord)
{
fileContents[i] = string.Format("{0}{1} {2}"
qrRecord, RoboReporterConstsAndUtils.COMPLETED_FLAG, DateTime.Now);
}
}
// Will this automatically overwrite the existing?
File.Delete(fileToUpdate);
File.WriteAllLines(fileToUpdate, fileContents);
}
catch (Exception ex)
{
RoboReporterConstsAndUtils.HandleException(ex);
}
}
したがって、ファイルを削除しますが、すぐに置き換えます。
File.Delete(fileToUpdate);
File.WriteAllLines(fileToUpdate, fileContents);
読み取られるファイルには、次のような内容が含まれます。
Opas,20170110,20161127,20161231-COMPLETED 1/10/2017 12:33:27 AM
Opas,20170209,20170101,20170128-COMPLETED 2/9/2017 11:26:04 AM
Opas,20170309,20170129,20170225-COMPLETED
Opas,20170409,20170226,20170401
レコード/行/行の最後に「-COMPLETED」が表示されている場合、無視されます - 処理されません。
また、2 番目の要素 (インデックス 1) が将来の日付である場合、(まだ) 処理されません。
したがって、上記の例では、最初の 3 つが既に実行されており、以降は無視されます。4 番目のものは、2017 年 4 月 9 日以降まで処理されません (この時点で、最後の 2 つの日付のデータ範囲内のデータが取得されます)。
ファイルが時々削除されるのはなぜですか? それが起こらないようにするにはどうすればよいですか?
役立つ場合、より多くのコンテキストで、ロジックは次のようになります。
internal static string GenerateAndSaveDelPerfReports()
{
string allUnitsProcessed = String.Empty;
bool success = false;
try
{
List<String> delPerfRecords = ReadFileContents(DelPerfFile);
List<QueuedReports> qrList = new List<QueuedReports>();
foreach (string qrRecord in delPerfRecords)
{
var qr = ConvertCRVRecordToQueuedReport(qrRecord);
// Rows that have already been processed return null
if (null == qr) continue;
// If the report has not yet been run, and it is due, add i
to the list
if (qr.DateToGenerate <= DateTime.Today)
{
var unit = qr.Unit;
qrList.Add(qr);
MarkAsProcessed(DelPerfFile, qrRecord);
if (String.IsNullOrWhiteSpace(allUnitsProcessed))
{
allUnitsProcessed = unit;
}
else if (!allUnitsProcessed.Contains(unit))
{
allUnitsProcessed = allUnitsProcessed + " and "
unit;
}
}
}
foreach (QueuedReports qrs in qrList)
{
GenerateAndSaveDelPerfReport(qrs);
success = true;
}
}
catch
{
success = false;
}
if (success)
{
return String.Format("Delivery Performance report[s] generate
for {0} by RoboReporter2017", allUnitsProcessed);
}
return String.Empty;
}
ファイルが定期的に破棄されるのを防ぐために、このコードを鉄壁にするにはどうすればよいですか?
アップデート
問題が発生する頻度が非常に低いため、これを実際にテストすることはできませんが、File.Delete() と File.WriteAllLines() の間に「一時停止」を追加すると問題が解決するのでしょうか?
更新 2
私の質問に対する答えが何であるかは絶対にわからないので、これを答えとして追加しませんが、私の推測では、 File.Delete() と File.WriteAllLines() が近すぎて発生していたので、ファイルの古いコピーと新しいコピーの両方で削除が発生することがありました。
もしそうなら、2 つの呼び出しの間の一時停止は 99.42% の時間で問題を解決したかもしれませんが、私がここで見つけたものから、File.Delete() はとにかく冗長/余分であるように見えるので、File.Delete でテストしました() がコメントアウトされ、問題なく動作しました。だから、私は今、時折問題となる電話をせずにやっています。それが問題を解決することを期待しています。