1

リーダーを閉じて破棄することでこの問題を解決したと思っていましたが、それでもファイルが使用されている場合がありました。次にガベージコレクターを呼び出したので、ファイルが解放されます。これにより、このエラーが発生するすべての問題の 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();

4

3 に答える 3

1

あなたが言っているように、それは時々しか起こらないと言っているだけで、ロックが保持されているだけかもしれません。キャッシュされたロックを取り除きます。このような方法を使用して、ファイルがまだ使用されているかどうかを確認する場合:

public bool CheckIfFileIsBeingUsed(string fileName){

     try{    
         File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
          }

      catch (Exception exp){
               return true;
        }

      return false;

}

false が返された場合は、先に進んでファイルを削除します。それ以外の場合は、待ってからもう一度チェックを実行してください。

于 2012-05-31T14:03:43.810 に答える
0

注:これはおそらくコメントであるはずですが、追加のスペースが必要です。

このコードは意味がありません:

// Prepare variables
string path = Path.GetTempPath();

// Write the file to the temp folder
using (FileStream fs = new FileStream(path, FileMode.Create))

パスは一時ファイルのディレクトリです。その名前のファイルを作成することはできません。

さらに、ここではFileNameという変数を使用します。

protected void DeleteFile()
{
    // Delete the file
    if (FileName != null && File.Exists(FileName))
        File.Delete(FileName);
}

ただし、WriteFileでは、_FileNameという変数を使用しています。

// Was the writing successfully completed?
_FileName = File.Exists(path) ? path : null;

私の推測では、上記に基づいて、あなたはあなたが書いていると思うものを書いていません、またはあなたが削除していると思うものを削除していません。

于 2012-05-31T16:27:17.317 に答える