リーダーを閉じて破棄することでこの問題を解決したと思っていましたが、それでもファイルが使用されている場合がありました。次にガベージコレクターを呼び出したので、ファイルが解放されます。これにより、このエラーが発生するすべての問題の 99% が解決されます。使用したコード:
public override void Finish()
{
// Kill the reader!
if (_reader != null)
{
_reader.Close();
_reader.Dispose();
// Make sure the server doesn't hold the file
GC.Collect();
}
DeleteFile();
}
Finish は、ファイルのコンテンツを処理する大きなプロセスの後に呼び出されます。
1 行 (または非常に少ない行) のファイルを処理すると、このエラーが発生することがあります。Windowsが速すぎてDeleteFile();
失敗するようです。このエラーを再現するのは非常に困難ですが、2 回続けて発生することがあります。
これは、処理に 2 秒以上かかるファイルを処理する場合には発生しません。
ファイルがGBになる可能性があり、Windowsはメモリがいっぱいになるとそれを好まないため、使用できません。また、この方法でプロセスのパフォーマンスが向上します。
質問:
このエラーを防ぐために他にできることはありますか?
PS: 詳細については、お気軽にお問い合わせください。
編集:
ファイルを削除するコード
protected void DeleteFile()
{
// Delete the file
if (FileName != null && File.Exists(FileName))
File.Delete(FileName);
}
ファイルを作成するコード
protected void WriteFile()
{
// Prepare variables
string path = Path.GetTempPath();
path += "\\MyTempFile";
// Modifiy path to avoid overwriting an existing file.
path += ".csv";
// Write the file to the temp folder
using (FileStream fs = new FileStream(path, FileMode.Create))
{
fs.Write(MyFile, 0, MyFile.Length);
}
// Was the writing successfully completed?
_FileName = File.Exists(path) ? path : null;
}
リーダーを作成するコード
protected override void ReadFile()
{
if (FileName == null)
WriteFile();
// Read the lines
_reader = new StreamReader(FileName, Encoding.Default, true);
while (_reader.Peek() != -1)
{
TotalRows++;
_reader.ReadLine();
}
// Read the lines
_reader = new StreamReader(FileName, Encoding.Default, true);
}
抽象クラスを使用して、入力の読み取り方法を決定します。次のステートメントで、ファイルの内容をループします。
while (FileReader.NextRow(out currentRow, out currentRowNumber))
{
// Process current Row...
}
メソッド NextRow() は次のようになります
public override bool NextRow(out List<object> nextRow, out int rowNumber)
{
if (RowNumber > TotalRows)
{
nextRow = null;
rowNumber = 0;
return false;
}
// Set the row number to return
rowNumber = RowNumber;
// Prepare the row
nextRow = _reader.ReadLine().ExtensionThatProcessesTheRow();
RowNumber++;
return true;
}
while ループが閉じた後、finish プロセスを呼び出します。FileReader.Finish();