0

Я это просто для:Parallel Для и фона рабочего

 for (int i = 0; i < nro_archivos; ++i) //Cargar el objeto img 
     { 
      string nombrearchivo = archivosdicom[i].FullName; 
      img.Add(new ImagenDicom(nombrearchivo)); 
      Progress_Bar_Loading_Images.PerformStep(); 
     } 

следуют этим:

decimal[] sliceseparation_imagen = new decimal[img.Count - 1]; 
     for (int i = 0; i < img.Count; i++) 
     { 
      if (i < img.Count - 1) 
      { 
       sliceseparation_imagen[i] = Math.Abs(img[i + 1].Z - img[i].Z); 
      } 
     } 
     sliceseparation_promedio = sliceseparation_imagen.Average(); 

Теперь моя задача состоит в том: я реализовал Paralell Для но не может использовать ProgressBar .. поэтому я думал об использовании BackgroundWorker, но проблема в том, что операция сразу после for зависит от нагрузки объекта img, которая происходит в этом так, пока это не будет выполнено. Я не могу продолжить. Мое понимание BackGroundWorker заключается в том, что он выполняется в фоновом режиме, в то время как основная программа продолжает выполнение, поэтому такой подход приведет к ошибкам при попытке получить доступ к объекту img, который не был создан к тому времени, когда основная программа достигает кода вне ,

Стоит ли использовать Фоновый Работник в этом случае, чтобы ускорить загрузку объекта img? если это так, как я могу подождать, пока работник фона выполнит свою работу, а затем продолжит выполнение основной программы? Мне нужно сообщить о прогрессе в работе для пользователя, поэтому использование параллели без чего-то, что позволит мне сообщить об этом пользователю, не будет работать. Спасибо, Матиас.

+0

Одна вещь о Фоновом Работнике заключается в том, что его задача состоит в выполнении длительной вычислительной работы в фоновом режиме, в то время как обновление пользовательского интерфейса можно обрабатывать через основной поток. И вы можете обрабатывать такие события, как DoWork, ProgressChanged - для отчета о состоянии, которое может быть использовано для обновления Progressbar в вашем случае. –

+0

Спасибо, Остин, это отлично работает для меня, проблема связана с кодом, который продолжает выполняться в основном потоке , он использует объект, который загружается в for (который был бы внутри рабочего фона, если я решил реализовать это), поэтому пока он не завершится, я не могу сделать много иначе, иначе он будет вызывать ошибки, пытающиеся получить доступ объекты, которые еще не загружены – Matias

ответ

0

Использование задач может помочь

var tasks = new List<Task> 
{ 
    Task.Run(() => { /* for loop logiC#1 */ 
      /* when interacting w/UI either use Dispatcher 
       for WPF for control.Invoke in winforms */ 
     }), 
    Task.Run(() => { /* for loop logiC#2 */}) 
}; 
Task.WaitAll(tasks.ToArray()); 
+0

Это может сработать, но у меня все еще есть проблема с сообщением о прогрессе с индикатором прогресса.Он получит доступ к нему из-за пределов основного потока, вызвав ошибку. – Matias

+0

При обновлении индикатора выполнения вызовите его в потоке пользовательского интерфейса, чтобы избежать исключения перекрестного потока. Существуют разные способы сделать это (wpf vs winforms и т. Д.). Может помочь следующая ссылка. http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c –

1

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

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

Вместо параллельной работы вы можете выполнять задачи. Доступ к пользовательскому интерфейсу через диспетчер UI, поэтому вам не нужно беспокоиться о проблемах с доступом к потоку пользовательского интерфейса.

var tasks = new List<Task> 
{ 
    Task.Run(() => { 
    // Block 1 
    // Use a proper dispatcher here to access the UI thread so you can report your progress}), 
}; 
Task.WaitAll(tasks); 

Теперь у вас есть ваши грузы, и вы можете продвигаться со своим вторым блоком работы.

Но, как я вижу, вам нужно только average, и вам не нужен правильный заказ, чтобы получить среднее значение.

var tasks = new List<Task> 
     { 
      Task.Run(() => { /* for loop logiC#1 */}) 
      .ContinueWith((x)=> { 
       // Get your task result and execute second block 
      }) 
     }; 
    Task.WaitAll(tasks); 

Теперь у вас есть постоянная задача, и все, что вам нужно сделать, это позвонить в среднем после того, как это будет сделано.

Вы можете пойти и с двумя отдельными блоками. Я решил, что, поскольку эти задачи переплетаются, почему вы не можете просто продолжать одну задачу в любом случае.