提问人:mehrshad 提问时间:10/20/2023 最后编辑:mehrshad 更新时间:10/31/2023 访问量:51
使用 cmd 进程发送的进度百分比更新进度条
Updating progress bar using progress percentage sent by a cmd process
问:
我是 C# Windows 窗体的新手。我想使用从 cmd 进程接收的标准输出数据更新程序中的进度条。
起初它不允许我更新栏并给了我错误。因此,我去异步启动了该过程,并将一个处理程序挂接到并用于逐行异步读取数据,并将一个传递给处理程序,该处理程序将调用另一个事件来更新进度条。can not access the bar from multiple threads
OutputDataReceived
process.BeginOutputReadLine()
IProgress<ProgressReportDataModel>
唯一的问题是进度百分比数据都集中在一行中,当调用事件时,进程已经完成进度条跳转到 100%。如何在此处更新进度条?OutputDataReceived
下面的代码是调用的方法:Task.Run()
private int FlasherRun(string args, IProgress<ProgressReportDataModel> progress)
{
ProgressReportDataModel report = new(); // for resetting bar when finished
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = programmerFileName;
startInfo.Arguments = args;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
process.StartInfo = startInfo;
process.OutputDataReceived +=
(Object _sender, DataReceivedEventArgs _args)
=> FlasherOutputHandler(_sender, _args, progress);
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
// Reset progress bar
report.progressPercentageComplete = 0;
progress.Report(report);
return process.ExitCode;
}
下面的函数是接收数据的处理程序:
private void FlasherOutputHandler(object sendingProcess, DataReceivedEventArgs outLine,
IProgress<ProgressReportDataModel> progress)
{
ProgressReportDataModel report = new ProgressReportDataModel();
// extract percentage value from outLine.Data and then
report.progressPercentageComplete = percentageValue;
report.progressMessages = someMessage;
progress.Report(report);
}
在调用第一个函数 async 之前,将挂接到下面的事件处理程序:progress.ProgressChanged
private void ReportProgressEvent(object? sender, ProgressReportDataModel e)
{
progressBar.Value = e.progressPercentageComplete;
messagesTextBox.Text += e.progressMessages;
}
下面是实例化和调用 FlasherRun 方法异步的方法。Progress<>
private async void btn_Click(object sender, EventArgs e)
{
try
{
Progress<ProgressReportDataModel> progress = new Progress<ProgressReportDataModel>();
progress.ProgressChanged += ReportProgressEvent;
string flasherCMD = "some command";
int exitCode = 0;
exitCode = await Task.Run(() => FlasherRun(flasherCMD, progress));
if (exitCode != 0)
{
MessageBox.Show("Error", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
catch (Exception exception)
{
// exceptions are handled here
}
}
我尝试在 while() 循环中使用方法一次一个字符读取来自标准输出的数据,并在传入数据中有新的可用百分比时调用进度更新,但这似乎没有在读取过程中调用进度更新程序事件,并且在阅读器完成并退出 while() 循环后,它以 100% 调用更新程序 20 次value,这是通过 streamreader 传入的最后一个值。process.StandardOutput.Read()
答: 暂无答案
评论
IProgress<ProgressReportDataModel>
FlasherRun
process.WaitForExit();
FlasherRun
ThreadPool