0

私の現在のプロジェクトでは、問題のファイルが他のプロセスによって使用されているという不平を言うランダムなエラーに直面しています。

高速に動作し、すべてがうまくいく場合もあれば、機能せず、エラーが発生し続ける場合もあります

ファイルは別のプロセスによって使用されています

したがって、削除メソッドを a 内に配置try-catchし、キャッチ内に、ファイルを削除しようとする、またはさらに良い方法で、ロックを解除して削除できるようにするある種のループがあると考えました。

そのループ内で別の例外が発生するかどうか、およびそれを管理する方法がわかりません。そのプロセスをファイルから切り離し、削除できるようにする解決策を見つけるにはどうすればよいですか?

アップデート

これは現時点での私のコードです:

 private void Test(string imagePath)
 {
        try
        {
            if (File.Exists(imagePath))
            {
                pictureBoxExistingPicture.Visible = true;
                labelnew.Visible = true;
                labelold.Visible = true;
                pictureBoxExistingPicture.Image = ImageUtility.SafeLoadImage(imagePath);

                if (MessageBox.Show("Do you want to overwrite the existing image?", "warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
                {
                    pictureBoxExistingPicture.Image = Properties.Resources._default;//restore default

                    while (true)
                    {
                        try
                        {
                            File.Delete(imagePath);
                            break;
                        }
                        catch (Exception)
                        {
                        }
                    }

                    pictureBoxHonarjo.Image.Save(imagePath);
                }
                else
                {
                    pictureBoxHonarjo.Image = ImageUtility.SafeLoadImage(imagePath);//restore original image
                }

                pictureBoxExistingPicture.Visible = false;
                labelnew.Visible = false;
                labelold.Visible = false;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

件名の現在のコンテキストでは、ユーザーが画像を置き換えたい場合は、それを行う必要があり、長い時間がかからず、失敗するべきではないと言う必要があります.だから基本的に誰かがしようとしたとき画像を変更すると、わずかな時間で変更する必要があります。

SafeLoadImage関数については、ここに私の実装があります:

public class ImageUtility
{
   public static byte[] ImageToBytes(string FilePath, int FileLength)
   {
      FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
      BinaryReader breader = new BinaryReader(fileStream);
      return breader.ReadBytes(FileLength);
    }

    public static Image SafeLoadImage(string imagePath)
    {
        byte[] image_byte;
        Image image;
        FileInfo fileinfo = new FileInfo(imagePath);
        image_byte = ImageUtility.ImageToBytes(imagePath, (int)fileinfo.Length);
        image = ImageUtility.BytesToImage(image_byte);
        return image;
    }
}
4

4 に答える 4

1

ここにファイルを削除しようとするループがあります:

protected virtual bool IsFileLocked(FileInfo file) 

{FileStreamストリーム=null;

try 
{ 
    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
} 
catch (IOException) 
{ 
    //the file is unavailable because it is: 
    //still being written to 
    //or being processed by another thread 
    //or does not exist (has already been processed) 
    return true; 
} 
finally 
{ 
    if (stream != null) 
        stream.Close(); 
} 

//file is not locked 
return false; 

}

FileInfo file = new FileInfo("PathToTheFile"); 
while (IsFileLocked(file)) 
    Thread.Sleep(1000); 
file.Delete(); 

プロセスエクスプローラーを使用して、ファイルhttp://technet.microsoft.com/en-us/sysinternals/bb896653.aspxへのプロセスアクセスを確認することもできます。

于 2012-08-15T10:31:52.713 に答える
1

ImageUtility.ImageToBytes終了時に FileStream を破棄しません

ファイルをロックしているのはこれでしょうか?

public static byte[] ImageToBytes(string FilePath, int FileLength) 
{ 
    FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read); 
    BinaryReader breader = new BinaryReader(fileStream); 
    return breader.ReadBytes(FileLength); 
}

実行がコード ブロックを終了した後にリソースを解放するステートメントを考えてみましょうusing(IDisposable をラップし、dispose メソッドを呼び出します)。

public static byte[] ImageToBytes(string FilePath, int FileLength) 
{ 
    using(FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read)) 
    {
        BinaryReader breader = new BinaryReader(fileStream); 
        return breader.ReadBytes(FileLength); 
    }
}

これが、ファイルがロックされている理由である可能性があります。

もちろん、他の誰かがあなたのファイルをロックしている場合、これは役に立たないかもしれません:)しかし、これらはあなたが作成した/処理している画像ファイルであると思われます

于 2012-08-15T10:42:52.167 に答える
1

わかった

したがって、次のような擬似コードがあります。

success = false
while not success
..try
..  delete file
..  success = true
..catch
..  wait a second
while end

再試行カウンターを追加して、運が良ければ無限にループしないようにすることができます。

あなたは自分のコードを何も与えなかったので、意図的にコードを含めませんでしたが、試してみる何かのテンプレートを与えました

于 2012-08-15T10:10:17.870 に答える
0

MessageBox を使用した私の簡単なソリューション:

bool deleted= false;
while(!deleted)
{
 try
  {
    File.Delete("path to file");                                 
    deleted = true;
  }
 catch 
  {
    MessageBox.Show("You can't delete file. Close file and press 'OK'");
    deleted = false; 
  }
}
于 2014-08-01T08:39:34.120 に答える