1

次のコードを使用して、フォルダー内のすべての画像をスケーリングおよびトリミングします。

string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
string fileExtension = Path.GetExtension(file);
string filePath = Path.GetDirectoryName(file);
string newFileName = string.Empty;
long fileSize = new FileInfo(file).Length;

if (fileSize > fileSizeLimit)
{
    string tempFile = System.IO.Path.GetTempFileName();
    File.Copy(file, tempFile, true);
    Bitmap sourceImage = (Bitmap)System.Drawing.Image.FromFile(tempFile);

    System.Drawing.Image imgPhoto = ScaleCrop(sourceImage, sourceImage.Width / 4, sourceImage.Height / 4, AnchorPosition.Top);
    Bitmap bitImage = new Bitmap(imgPhoto);
    File.Delete(file);

    newFileName = filePath + "\\" + fileNameWithoutExtension + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + CoilWarehouseProcessed + fileExtension;

    bitImage.Save(newFileName, System.Drawing.Imaging.ImageFormat.Jpeg);

    imgPhoto.Dispose();
    bitImage.Dispose();
}

アプリケーションをローカルで (VS2010 のデバッグ モードで) 実行し、それをネットワーク ドライブにポイントすると、毎回すべての画像が処理されます。

ローカル Web サーバーから実行すると、問題は、アプリが画像を処理しない場合、5 を処理する場合、1 を処理する場合、特定のフォルダー内のすべての画像を処理することはなく、一部の画像のみを処理することです...その後、クライアントのブラウザでハングします。

イベント ログを介して表示するイベントはありません...いずれにせよ、アプリケーションはクラッシュしたりエラーになったりしません...画像を処理するという事実は、それがアクセス許可の問題ではないことを証明しています。

なぜこれが起こっているのですか?

編集: wazdev のおかげで、私はあまり邪魔にならない (また、サードパーティのソフトウェアに依存する依存関係も好きではない) ソリューションをテストすることになりました。ストリームを使用して新しい画像 'System.Drawing.Image imgPhoto = ...' を生成し、using ステートメントを使用して 'temp' 画像が確実に破棄されるようにします。また、元の (トリミングされていない/スケーリングされていない画像) ファイルの削除を最後の操作になるように移動しました (テストでは問題なく動作しましたが、もう一度ユーザーがオンラインになり、同時実行性がテストされたら、時間が経てばわかります)。

string tempFile = System.IO.Path.GetTempFileName();
File.Copy(file, tempFile, true);
Bitmap sourceImage = (Bitmap)System.Drawing.Image.FromFile(tempFile);

System.Drawing.Image imgPhoto = ScaleCrop(sourceImage, sourceImage.Width / 4, sourceImage.Height / 4, AnchorPosition.Top);

Bitmap bitImage;

using (var bmpTemp = new Bitmap(imgPhoto))
{
    bitImage = new Bitmap(bmpTemp);
}

newFileName = filePath + "\\" + fileNameWithoutExtension + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_" + CoilWarehouseProcessed + fileExtension;

bitImage.Save(newFileName, System.Drawing.Imaging.ImageFormat.Jpeg);

imgPhoto.Dispose();
bitImage.Dispose();
File.Delete(file);

EDIT2:現在数日間稼働しており、毎日テストしましたが、うまく機能しています..これが私がしたことのすべてです。

基本的に、ScaleCrop() 呼び出しの内部には、GC.Collect と Wait For Pending Finalisers() 呼び出しがありました。保留中の呼び出しの待機を削除し、GC.Collect() を File.Delete() の後に移動しました。

4

1 に答える 1

2

過去に、RAM が使い果たされてディスクへのページングが発生したときに、この動作を見たことがあります。ImageResizing.net ライブラリを利用して多くの成功を収めました: http://imageresizing.net/

このライブラリを使用するようにコードを更新しましたが、振り返ることはありません。

HTH

(私は imageresizing.net とは何の関係もありません - 私はとても幸せなユーザーです)

于 2016-03-01T10:18:11.763 に答える