2015-02-02 7 views
1

Вот код по большей части:Удаление обратного вызова внутри для-каждого цикла

foreach (var file in dialog.Files.Where(someConditionsGoHere).AsEnumerable()) 
{ 
    Images imageRec = this.CreateNew<Images>(); 
    imageRec.Description = file.Name; 
    imageRec.AsOfDate = System.DateTime.Now; 
    // inits some more fields here 

    using (System.IO.Stream fileStream = file.OpenRead()) 
    { 
     byte[] fileBytes = new byte[System.Convert.ToInt32(fileStream.Length)]; 
     fileStream.Read(fileBytes, 0, fileBytes.Length); 

     if (imageRec.Extension.ToUpper() == "TIFF" || imageRec.Extension.ToUpper() == "TIF") 
     { 
      // pop a yes/no dialog to convert to PDF. 
      Action<UI.Interactivity.InteractionRequest.YesNoDialog.YesNoDialogConfirmation> callback = c => 
       { 
        if (c.Yes) 
        { 
         foreach (var tiffFile in dialog.Files) 
         { 
          string ext = tiffFile.Extension.Substring(1); 
          if (ext.ToUpper() != "TIF" && ext.ToUpper() != "TIFF") continue; 

          using (System.IO.Stream tiffFileStream = tiffFile.OpenRead()) 
          { 
           byte[] tiffFileBytes = 
            new byte[System.Convert.ToInt32(tiffFileStream.Length)]; 
           tiffFileStream.Read(tiffFileBytes, 0, tiffFileBytes.Length); 

           Images imageRec2 = this.CreateNew<Images>(); 
           imageRec2.Description = tiffFile.Name; 
           imageRec2.Extension = "pdf"; 
           // some more inits and sutff here too. 
           ImagingUtilities.ConvertImgToPDF(tiffFileBytes, imageRec2) 
          } 
         } 
        } 
        else 
        { 
         this.SaveAndAddImage(imageRec, fileBytes, file.Name); 
        } 
       }; 

      this.OpenYesNoDialog("Do you want to convert Tiff files to PDF before saving them?", callback); 

     } 
     else 
     { 
      this.SaveAndAddImage(imageRec, fileBytes, file.Name); 
     } 
    } 
} 

В настоящее время он показывает YesNo dialog в то время как цикл через образы в и если этот образ является ".tiff" файл это переходит к методу callback с диалогом YesNo, запрашивающим, хочет ли пользователь преобразовать его в PDF. Проблема в том, что я не хочу, чтобы он запрашивал у пользователя каждый файл tiff, я хочу, чтобы он запрашивал только один раз, поэтому я должен вынуть callback из for-each loop, но когда я это делаю, я теряю порядок, в котором команды получая вызов из-за атрибута async обратного вызова. Может кто-нибудь помочь с реструктуризацией этого?

+0

Вы видите, 'если (c.Yes)'? Считаете ли вы, что это может быть переменная, которую вы вводите? – CodeCaster

+0

Вы всегда можете сделать две петли. Первый, чтобы узнать, есть ли файл .tiff', затем запросите диалог YesNo. затем используйте вторую для преобразования файлов. –

+0

@CodeCaster yes Я могу сохранить ответ c.Yes в переменной, если это был ваш вопрос. – Bohn

ответ

1

без переписывания действительно, и просто перемещение кода вокруг, вы можете сделать это:

//any additional logic like filtering for if we have a tiff etc here. 

    Action<UI.Interactivity.InteractionRequest.YesNoDialog.YesNoDialogConfirmation> callback = c => 
      { 
       if (c.Yes) 
       { 
        foreach (var tiffFile in dialog.Files.Where(x=>x.Extension.ToUpper() == "TIFF" || x.Extension.ToUpper() == "TIF")) 
        { 


         using (System.IO.Stream tiffFileStream = tiffFile.OpenRead()) 
         { 
          byte[] tiffFileBytes = 
           new byte[System.Convert.ToInt32(tiffFileStream.Length)]; 
          tiffFileStream.Read(tiffFileBytes, 0, tiffFileBytes.Length); 

          Images imageRec2 = this.CreateNew<Images>(); 
          imageRec2.Description = tiffFile.Name; 
          imageRec2.Extension = "pdf"; 
          // some more inits and sutff here too. 
          ImagingUtilities.ConvertImgToPDF(tiffFileBytes, imageRec2) 
         } 
        } 
       } 
       else 
       { 
        this.SaveAndAddImage(imageRec, fileBytes, file.Name); 
       } 
      }; 

     this.OpenYesNoDialog("Do you want to convert Tiff files to PDF before saving them?", callback); 


    //tiff already handled 
    foreach (var file in dialog.Files.Where(x=>x.Conditions&& !x.Extension.ToUpper() == "TIFF" && !x.Extension.ToUpper() == "TIF").AsEnumerable()) 
    { 
     Images imageRec = this.CreateNew<Images>(); 
     imageRec.Description = file.Name; 
     imageRec.AsOfDate = System.DateTime.Now; 
     // inits some more fields here 

     using (System.IO.Stream fileStream = file.OpenRead()) 
     { 
      byte[] fileBytes = new byte[System.Convert.ToInt32(fileStream.Length)]; 
      fileStream.Read(fileBytes, 0, fileBytes.Length); 


      this.SaveAndAddImage(imageRec, fileBytes, file.Name); 

     } 

    } 
+0

Хмм, он по-прежнему задал вопрос Tiff для PDF, даже если выбранные изображения не являются Tiff – Bohn

+0

Да. Это будет, я не добавил никакой дополнительной логики, я просто переместил обратный вызов, чтобы его вызывали один раз. –

+0

Спасибо, исправлено, просто добавлено логическое значение, чтобы увидеть, были ли мы выбраны какие-либо tiffs, если да, то вызывайте this.OpenYesNoDialog, иначе ничего. – Bohn

1

Похоже, что у вас есть крайняя петля, которая выполняет итерации более dialog.Files, а затем еще один внутри обратного вызова, который выполняет итерацию более dialog.Files. Это слишком много уровней итерации.

Я думаю, вы можете исправить это, разбив это на несколько методов. Напишите способ ProcessFile, который принимает один объект File, и bool, представляющий, нужно ли его преобразовать в PDF (или что бы вы ни делали по-другому в своем обратном вызове) и обрабатывает его соответствующим образом.

Теперь вы можете заменить весь код, вы вставили здесь со следующим:

this.OpenYesNoDialog("...", ans => { 
    foreach(var file in dialog.Files.Where(someConditionsGoHere)) 
     ProcessFile(file, ans.Yes) 
}); 

Вот что я думаю, ProcessFile должен выглядеть на основе моего ограниченного понимания кода:

private void ProcessFile(File file, bool convertToPDF) 
{ 
    Images imageRec = this.CreateNew<Images>(); 

    imageRec.Description = file.Name; 
    imageRec.AsOfDate = System.DateTime.Now; 
    // ... 

    using (System.IO.Stream fileStream = file.OpenRead()) { 
     byte[] fileBytes = new byte[System.Convert.ToInt32(fileStream.Length)]; 
     fileStream.Read(fileBytes, 0, fileBytes.Length); 

     if (convertToPDF && (ext.ToUpper() == "TIF" || ext.ToUpper() == "TIFF")) 
     { 
      // Configure imageRec fields for PDF 
      imageRec.Extension = "pdf"; 
      // ... 

      ImagingUtilities.ConvertImgToPDF(tiffFileBytes, imageRec); 
     } 
     else 
     { 
      // Configure imageRec fields for everything else 
      // ... 

      this.SaveAndAddImage(imageRec, fileBytes, file.Name); 
     } 


    } 
} 
+0

Спасибо, я реструктурирую его так, как вы предлагаете, и посмотрите, как он себя ведет. – Bohn

+1

@Bohn Я представил реализацию 'ProcessFile', которая, как я думаю, должна работать. –

1

Грубый и жесткий для того, что вы наклеили. Вам нужно внести некоторые изменения в вызов pdf ConvertImgToPDF, чтобы вернуть массив байтов. Это удаляет двойной цикл и запрашивает только один раз для tiff.

var askedToConvert = false; 
    var convertTiff = false; 
    foreach (var file in dialog.Files.Where(someConditionsGoHere).AsEnumerable()) 
    { 
     Images imageRec = this.CreateNew<Images>(); 
     imageRec.Description = file.Name; 
     imageRec.AsOfDate = System.DateTime.Now; 
     // inits some more fields here 


     using (System.IO.Stream fileStream = file.OpenRead()) 
     { 
      byte[] fileBytes = new byte[System.Convert.ToInt32(fileStream.Length)]; 
      fileStream.Read(fileBytes, 0, fileBytes.Length); 

      if (imageRec.Extension.ToUpper() == "TIFF" || imageRec.Extension.ToUpper() == "TIF") 
      { 

       if(!askedToConvert) 
       {   
        this.OpenYesNoDialog("Do you want to convert Tiff files to PDF before saving them?", c=> { 
         askedToConvert = true; 
         convertTiff = c.Yes; 
        }); 
       } 
       if(convertTiff) 
       {   

        imageRec.Extension = "pdf"; 
        // some more inits and sutff here too.    
        fileBytes = ImagingUtilities.ConvertImgToPDF(fileBytes) ; // this needs to return new bytes  

       } 

       this.SaveAndAddImage(imageRec, fileBytes, file.Name); 

     } 
    } 
+0

есть ли причина var askToConvert = false; var convertTiff = false; находятся внутри каждого из них, а не из него? Благодарю. – Bohn

+0

@Bohn Хорошая добыча, да, они должны быть снаружи. – user3420988

Смежные вопросы