Индикатор выполнения в параллельном вызове цикла

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

public static void DO_Computation(//parameters) {
  //Intialisation of parameters

  Parallel.For(struct initialisation with local data) {
    //business logic
    //Call to update_progressbar (located in an another class, as the DO_Computation function is in Computation.cs class (not deriving from Form). 
    WinForm.Invoke((Action)delegate {Update_Progress_Bar(i);}); //WinForm is a class that exposes the  progressbar.
  }
}

Это не работает (индикатор прогресса останавливается при достижении 100%, что является нормальным (мы можем обратиться кстатья о майкрософт в этом вопросе (действительно, это не потокобезопасный метод работы)). Сайт Microsoft предусматривает обернутьParallel.For петля вTask рутина следующим образом:

public static void DO_Computation(//parameters) {
  //Intialisation of parameters
  Task.Factory.StartNew(() =>
  {
    Parallel.For(struct initialosation with local data) {
      //business logic
      //Call to update_progressbar (ocated in an another class, as the DO_Computation function is in Computation.cs class (not deriving from Form). 
      WinForm.Invoke((Action)delegate {Update_Progress_Bar(i);}); //WinForm is a class that exposes the  progressbar.
      ..
    }
  });
});

Однако это также не работает, когда отладка потока выходит непосредственно из области задач.

РЕДАКТИРОВАТЬ 2:

По сути, моя проблема делится на 3 части:Computation.cs (гдеDO_Computation разоблачен),WinForm это форма, содержащая индикатор выполнения, иMainWindow это форма, содержащая кнопку, которая при нажатии открывает форму с индикатором выполнения.

Я не совсем понимаю, что толку от «Задачи» в этом случае. Потому что он выходит за рамки задачи, не выполняя никакихParallel.For Работа

Есть идеи?

Большое спасибо,

РЕДАКТИРОВАТЬ 3:

Я обновил свой код с помощью Noseratio (ему большое спасибо). Однако у меня та же проблема, что код внутри задачи никогда не выполняется. Мой код теперь выглядит так:

DoComputation method //Some Initilasations here Action enableUI = () => { frmWinProg.SetProgressText("Grading Transaction..."); frmWinProg.ChangeVisibleIteration(true); }; Action<Exception> handleError = (ex) => { // error reporting MessageBox.Show(ex.Message); }; var cts = new CancellationTokenSource(); var token = cts.Token; Action cancel_work = () => { frmWinProg.CancelTransaction(); cts.Cancel(); }; var syncConext = SynchronizationContext.Current; Action<int> progressReport = (i) => syncConext.Post(_ => frmWinProg.SetIteration(i,GrpModel2F.NumOfSim, true), null); var task = Task.Factory.StartNew(() => { ParallelLoopResult res = Parallel.For<LocalDataStruct>(1,NbSim, options, () => new DataStruct(//Hold LocalData for each thread), (iSim, loopState, DataStruct) => //Business Logic if (token.IsCancellationRequested) { loopState.Stop(); } progressReport(iSim); //Business Logic return DataStruct; }, (DataStruct) => //Assiginig Results; });//Parallel.For end }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); task.ContinueWith(_ => { try { task.Wait(); } catch (Exception ex) { while (ex is AggregateException && ex.InnerException != null) ex = ex.InnerException; handleError(ex); } enableUI(); }, TaskScheduler.FromCurrentSynchronizationContext

());

Обратите внимание, что функция Do_Computation сама вызывается из формы, в которой запускается BackGroundWorker.

Ответы на вопрос(1)

Ваш ответ на вопрос