简体   繁体   English

运行进程时进度条未在UI中异步更新

[英]Progress bar is not updating asynchronously in UI while running a process

I have to update the progress bar and status label while executing a process.I am using a BackgroundWorker . 我必须在执行流程时更新进度条和状态标签。我正在使用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. DoWork Event中,我正在启动过程,而在执行过程时,我试图使用ReportProgress()和状态标签来更新进度条。我的问题是它只会在过程完成后才会更新。我必须并行进行。

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();
}

Anything you want to do on the UI as to be done on the UI Thread. 您想要在UI上完成的任何事情,都需要在UI线程上完成。 This will help: How to update the GUI from another thread in C#? 这将有所帮助: 如何从C#中的另一个线程更新GUI?

Basically what you need is to update progress on the UI thread: 基本上,您需要更新UI线程上的进度:

this.Invoke((MethodInvoker)delegate {
    Progress = 10; // runs on UI thread
});

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. 如果您在BackgroundWorker ,只需在该工作器处于活动状态时调用ReportProgress来更新Gui,则根本不要使用Dispatcher.BeginInvoke

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... 请注意 ,您不仅限于更新executionworker_ProgressChanged的进度条:从那里开始(利用传递的参数),您可以工作进行期间进行所需的所有 Gui更新...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM