0

I have to update the progress bar and status label while executing a process.I am using a BackgroundWorker. In DoWork Event i am starting the process and while executing the process i am trying to update progressbar using ReportProgress() and status label.My problem is it will update only after the completion of process.I have to do that in parallel.

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    executionworker.DoWork += executionworker_DoWork;
    executionworker.WorkerReportsProgress = true;
    executionworker.RunWorkerCompleted += executionworker_RunWorkerCompleted;
    executionworker.ProgressChanged += executionworker_ProgressChanged;
}

private void executionworker_DoWork(object sender, DoWorkEventArgs e)
{
    workerThread = Thread.CurrentThread;
    try
    {
        List<string> xmlDataList = new List<string>();
        counter = 0;
        starttime = DateTime.Now;
        sessionmgm.StartTime = starttime.ToString();
        string executionmode = Data[0].ExecutionMode;
        //string testDataMode = string.Empty;
        Decimal progress;
        bool deviceInstallStatus = false;
        bool deviceInvokeStatus = false;
        int progressCount = 0;
        int prevProgressCount = 0;
        bool childStatus = false;
        string id = string.Empty;
        string name = string.Empty;
        string description = string.Empty;
        String stepexePath = "";
        datamgm = new TestStepConfigurationManager();

        if (Directory.Exists(FilePaths.ResultPath + sessionmgm.ScriptName))
            Directory.Delete(FilePaths.ResultPath + sessionmgm.ScriptName, true);
        Directory.CreateDirectory(FilePaths.ResultPath + sessionmgm.ScriptName);
        String TestResultPath = FilePaths.ResultPath + sessionmgm.ScriptName + StatusCodes.TAC_SEPERATOR_BCKWDSLASH;              
        string stepXMLName = stepname = Data[0].Name;
        stepexePath = Data[0].ConfigPath;
        XDocument configdoc = XDocument.Load(Data[0].ConfigXMLPath);
        foreach (XElement xe in configdoc.Descendants("TATestStep"))
        {
            id = xe.Element("UniqueID").Value;
            name = xe.Element("Name").Value;
            description = xe.Element("Description").Value;
            scriptids = xe.Element("ScriptID").Value.Split(',');
            scriptids = scriptids.Where(s => !String.IsNullOrEmpty(s)).ToArray();
        }
        Dispatcher.BeginInvoke((Action)(() =>
           {
               add_Steps();
           }));
           progressCount = 3 / scriptids.Length;
           for (int j = 1; j <= progressCount; j++)
           {
               if (deviceInstallStatus) break;
               progress = j;
               progresspercent = (int)progress;
               (sender as BackgroundWorker).ReportProgress(progresspercent);
           }
           prevProgressCount = progressCount;
           configdoc = XDocument.Load(FilePaths.ApplicationPath + StatusCodes.TAC_Configfile);
           foreach (XElement xe in configdoc.Descendants("TATool"))
           {
               commandPath = xe.Element("MainFolderPath").Value;
           }
           for (int i = 0; i < scriptids.Length; i++)
           {                   
               TestStep = Path.GetFileName(Path.GetDirectoryName(stepexePath));
               UpdateWorkflowStatus("Executing: " + TestStep + "...");
               string screenshotErrorPath = Path.GetDirectoryName(stepexePath);
               TestSuitePath = Path.GetDirectoryName(Path.GetDirectoryName(stepexePath));
               stepcount = Directory.GetFiles(TestResultPath, "*.xml").Where(file => Regex.IsMatch(Path.GetFileName(file), TestStep + "_" + "[0-9]") || Regex.IsMatch(Path.GetFileName(file), TestStep + ".xml")).Count();
               if (stepcount > 0)
                   ResultPath = TestResultPath + TestStep + "_" + i + ".xml";
               else
                   ResultPath = TestResultPath + TestStep + ".xml";

               toolarguments.Add("ResultPath", ResultPath);
               toolarguments.Add("TestSuitePath", TestSuitePath);
               toolarguments.Add("TestStep", TestStep);
               toolarguments.Add("DataPath", datapath);
               toolarguments.Add("StepCount", stepcount.ToString());
               toolarguments.Add("Name", name);
               toolarguments.Add("UniqueID", id);
               toolarguments.Add("Description", description);
               toolarguments.Add("ScreenShotPath", screenshotErrorPath);
               Dispatcher.BeginInvoke((Action)(() =>
               {
                   StartExecutionByFramework(toolarguments);

               }));
               string statusContent = string.Empty;
               int progressRange = 0;
               bool completionStatus = false;
               while (executionFrameworkStatus < 2)
               {
                   if (executionFrameworkStatus == 1)
                   {
                       UpdateStatusLabel(out statusContent, out                                        progressRange, out completionStatus);
                       if (completionStatus)
                       {
                           Dispatcher.BeginInvoke((Action)(() =>
                           {
                               lblstatus.Content = statusContent;
                           }));
                   for (int j = prevProgressCount;j<=progressRange;j++)       
                           {
                               progress = j;
                               progresspercent = (int)progress;
                               executionworker.ReportProgress(progresspercent);
                           }
                           prevProgressCount = progressRange;
                       }      
                   }                  
               } 
             step_endtime = DateTime.Now;
             step_tm = step_endtime - step_starttime;
             step_totaltime = step_tm.Minutes + " Minutes: " + step_tm.Seconds + " Seconds";
             string reportFile = string.Empty;
             string screenshotfile = string.Empty;
             prevProgressCount = progressCount;
             progressCount = Decimal.ToInt32(Decimal.Divide(counter+1,scriptids.Length) * 83);
             for (int j = prevProgressCount; j <= progressCount; j++)
             {
                 progress = j;
                 progresspercent = (int)progress;
                 (sender as BackgroundWorker).ReportProgress(progresspercent);
             }
             Dispatcher.BeginInvoke((Action)(() =>
             {
                 lblstatus.Content = "Report Generation" + " of" + " " + Data[0].Name +" " + "in Progress...";
             }));
             if (objToolDataStore.ReportGeneration(toolarguments))
             {
                 UpdateProgressStatus(out reportFile, out screenshotfile);
                 errorfile = datamgm.GetErrorLogs(screenshotfile);
                 datamgm.GenerateReport(TestStep, reportFile, step_totaltime, errorfile, childStatus);
             }
             prevProgressCount = progressCount;
             progressCount = Decimal.ToInt32(Decimal.Divide(counter+1,scriptids.Length) * 92);
             for (int j = prevProgressCount; j <= progressCount; j++)
             {
                 progress = j;
                 progresspercent = (int)progress;
                 (sender as BackgroundWorker).ReportProgress(progresspercent);
             }
         }                
         //objToolDataStore.CleanAUT(toolarguments);
         progress = 100;
         progresspercent = (int)progress;
         (sender as BackgroundWorker).ReportProgress(progresspercent);               
     }
     catch (ThreadAbortException)
     {
         e.Cancel = true;
         Thread.ResetAbort();
     }
 }

public Boolean StartExecutionByFramework(Dictionary<String, String> toolarguments)
{
    string mainCommand = string.Empty;
    string binPath = string.Empty;
    string exeFileName = string.Empty;
    string ModeratorPath = string.Empty;
    string commandXmlPath = string.Empty;
    string mainFolderPath = string.Empty;
    String ServerArguments = string.Empty;
    Process P;
    XDocument configdoc = XDocument.Load(FilePaths.ApplicationPath + StatusCodes.TAC_Configfile);
    foreach (XElement xe in configdoc.Descendants("TATool"))
    {
        commandXmlPath = xe.Element("CommandFilePath").Value;
        mainFolderPath = xe.Element("MainFolderPath").Value;
    }
    if (!string.IsNullOrEmpty(commandPath))
    {
        XDocument commanddoc = XDocument.Load(commandXmlPath);
        foreach (XElement xe in commanddoc.Descendants("Tool"))
        {
            if (xe.Element("ToolName").Value == "Squish")
            {
                mainCommand = objToolDataStore.GetLanguagePath(@"Software\Microsoft\Windows\CurrentVersion\App Paths\python.exe");
                ModeratorPath = mainFolderPath + xe.Element("ModeratorPath").Value;
                exeFileName = Path.GetFileName(mainCommand);

                //Main command
                ServerArguments = ModeratorPath +
                    StatusCodes.TAC_SEPERATOR_SPACE + toolarguments["UniqueID"];
                break;
            }
        }
    }
    P = new Process();
    try
    {
        if (P != null)
        {
            P.StartInfo.WorkingDirectory = mainCommand;
            P.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            P.StartInfo.FileName = exeFileName;
            P.StartInfo.Arguments = ServerArguments;
            executionFrameworkStatus = 1;
            P.Start();
            P.WaitForExit(480000);
        }
    }
    catch (Exception ex)
    {
        string msg = ex.Message;
        processStatus = false;
        //P.CloseMainWindow();
        //P.Close();
        return processStatus;
    }
    processStatus = true;
    executionFrameworkStatus = 2;
    return processStatus;
}

private void executionworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressbar.Value = e.ProgressPercentage;
}

private void executionworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{

    endtime = DateTime.Now;

    if (!e.Cancelled)
    {
        UpdateWorkflowStatus("Execution Completed.");
    }
    else
    {
        UpdateWorkflowStatus("Execution Failed.");
        lblSelectTools.Visibility = Visibility.Visible;
        SelectToolsTable.Visibility = Visibility.Visible;
        lblSelectedTool.Visibility = Visibility.Visible;
        lblToolName.Visibility = Visibility.Visible;
        grdView.Visibility = Visibility.Visible;
        lblDescription.Visibility = Visibility.Hidden;
        lstSteps.Visibility = Visibility.Hidden;
    }
    // sessionmgm.ScriptName = "";
    endtime = DateTime.Now;
    tm = (endtime - starttime);
    totaltime = tm.Hours + " Hours: " + tm.Minutes + " Minutes: " + tm.Seconds + " Seconds";
    sessionmgm.Time = totaltime;
    sessionmgm.EndTime = endtime.ToString();
    sessionmgm.TotalSteps = ((counter+1) - 1).ToString();
    sessionmgm.Iteration = iterationcount.ToString();
    resetevent.Reset();
    btnPlay.IsEnabled = true;
    btnStop.IsEnabled = false;
    executionworker.Dispose();
}
Anu Hardin
  • 65
  • 8
  • Possible duplicate of [Accessing UI (Main) Thread safely in WPF](http://stackoverflow.com/questions/11625208/accessing-ui-main-thread-safely-in-wpf) – Abin Aug 05 '16 at 14:05

2 Answers2

1

Anything you want to do on the UI as to be done on the UI Thread. This will help: How to update the GUI from another thread in C#?

Basically what you need is to update progress on the UI thread:

this.Invoke((MethodInvoker)delegate {
    Progress = 10; // runs on UI thread
});
Community
  • 1
  • 1
Ouarzy
  • 3,015
  • 1
  • 16
  • 19
  • Yes It normally should. – Ouarzy Aug 08 '16 at 09:35
  • But it is not working for me.When I used Invoke instead of BeginInvoke control will wait for the execution to complete.It is not updating to the UUI.Please find the code below – Anu Hardin Aug 08 '16 at 10:03
  • Dispatcher.BeginInvoke((Action)(() => { StartExecutionByFramework(toolarguments); })); string statusContent = string.Empty; int progressRange = 0; bool completionStatus = false; – Anu Hardin Aug 08 '16 at 10:09
  • while (executionFrameworkStatus < 2) { if (executionFrameworkStatus == 1) { UpdateStatusLabel(out statusContent, out progressRange, out completionStatus); if (completionStatus) { lblstatus.Dispatcher.Invoke((System.Windows.Forms.MethodInvoker)delegate { lblstatus.Content = statusContent; }); – Anu Hardin Aug 08 '16 at 10:09
  • progressbar.Dispatcher.Invoke((System.Windows.Forms.MethodInvoker)delegate { for (int j = prevProgressCount; j <= progressRange; j++) { progress = j; progresspercent = (int)progress; progressbar.Value = progresspercent; } prevProgressCount = progressRange; }); } } } – Anu Hardin Aug 08 '16 at 10:10
0

If you are in a BackgroundWorker, just call ReportProgress to update the Gui while the worker is active, don't use Dispatcher.BeginInvoke at all.

Notice that you are not limited to updating only the progress bar in the executionworker_ProgressChanged: from there (leveraging the argument passing) you can do all the Gui updating needed while work is in progress...