运行进程时,进度条未在UI中异步更新
本文关键字:UI 异步 更新 进程 运行 | 更新日期: 2023-09-27 18:01:04
在执行进程时,我必须更新进度条和状态标签。我正在使用BackgroundWorker
。在DoWork
事件中,我正在启动进程,在执行进程时,我试图使用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();
}
您想在UI上做的任何事情都将在UI线程上完成。这将有助于:如何从C#中的另一个线程更新GUI?
基本上,你需要的是在UI线程上更新进度:
this.Invoke((MethodInvoker)delegate {
Progress = 10; // runs on UI thread
});
如果您在BackgroundWorker
中,只需在工作进程处于活动状态时调用ReportProgress
来更新Gui,根本不要使用Dispatcher.BeginInvoke
。
请注意您不仅限于更新executionworker_ProgressChanged
中的进度条:从那里(利用参数传递(,您可以在工作进行时执行所有所需的Gui更新。。。