0

まず、私の免責事項:私は並行初心者です。これは簡単に「恥ずかしいほど並列」の問題に取り組むことができると思っていましたが、ループに陥ってしまいました。

ウェブからいくつかの写真を並行してダウンロードしようとしています。元の写真は高解像度でかなりの容量を占めるので、ダウンロードしたら圧縮します。

コードは次のとおりです。

    private static void DownloadPhotos(ISet<MyPhoto> photos)
    {
        List<MyPhoto> failed = new List<MyPhoto>();

        DateTime now = DateTime.Now;
        string folderDayOfYear = now.DayOfYear.ToString();
        string folderYear = now.Year.ToString();
        string imagesFolder = string.Format("{0}{1}\\{2}\\", ImagePath, folderYear, folderDayOfYear);

        if (!Directory.Exists(imagesFolder))
        {
            Directory.CreateDirectory(imagesFolder);
        }

        Parallel.ForEach(photos, photo =>
        {
            if (!SavePhotoFile(photo.Url, photo.Duid + ".jpg", imagesFolder))
            {
                failed.Add(photo);
                Console.WriteLine("adding to failed photos: {0} ", photo.Duid.ToString());
            }
        });

        Console.WriteLine();
        Console.WriteLine("failed photos count: {0}", failed.Count);

        RemoveHiResPhotos(string.Format(@"{0}\{1}\{2}", ImagePath, folderYear, folderDayOfYear));
    }


    private static bool SavePhotoFile(string url, string fileName, string imagesFolder)
    {
        string fullFileName = imagesFolder + fileName;
        string originalFileName = fileName.Replace(".jpg", "-original.jpg");
        string fullOriginalFileName = imagesFolder + originalFileName;

        if (!File.Exists(fullFileName))
        {
            using (WebClient webClient = new WebClient())
            {
                try
                {
                    webClient.DownloadFile(url, fullOriginalFileName);
                }
                catch (Exception ex)
                {
                    Console.WriteLine();
                    Console.WriteLine("failed to download photo: {0}", fileName);
                    return false;
                }
            }
            CreateStandardResImage(fullOriginalFileName, fullOriginalFileName.Replace("-original.jpg", ".jpg"));
        }
        return true;
    }

    private static void CreateStandardResImage(string hiResFileName, string stdResFileName)
    {
        Image image = Image.FromFile(hiResFileName);
        Image newImage = image.Resize(1024, 640);
        newImage.SaveAs(hiResFileName, stdResFileName, 70, ImageFormat.Jpeg);
    }

ここで私は混乱します。各写真は、webClient.DownloadFile行の SavePhotoFile() メソッドの Catch{} ブロックにヒットします。エラー メッセージは、WebClient 要求中に発生した例外であり、内部の詳細は「別のプロセスによって使用されているため、プロセスはファイル . . . -original.jpg にアクセスできません。」です。

このエラーで十分に混乱していなかったとしたら、次に何が起こるかでさらに混乱します。メッセージを無視して待つと、最終的に画像がダウンロードされて処理されることがわかりました。

どうしたの?

4

1 に答える 1

0

さて、並列処理に焦点を当てていると、単純なエラーが発生したように見えます。データについて、正しくないことを想定していました。Brianesteyは問題を理解しました:Duidはユニークではありません。リストを作成するプロセスで欠落しているコードを除いて、これは一意であると想定されています。

修正は、これをMyPhotoクラスに追加することでした

    public override bool Equals(object obj)
    {
        if (obj is MyPhoto)
        {
            var objPhoto = obj as MyPhoto;
            if (objPhoto.Duid == this.Duid)
                return true;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return this.Duid.GetHashCode();
    }
于 2012-06-11T14:06:31.347 に答える