C# Backgroundworker ReportProgress() 未执行
C# Backgroundworker ReportProgress() not executing
您好,我正在尝试填充进度条,但 ReportProgress 调用由于某种原因未被执行。
这是我的代码
//create status_Worker
status_Worker = new BackgroundWorker();
status_Worker.DoWork += new DoWorkEventHandler(Status_DoWork);
status_Worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
status_Worker.WorkerReportsProgress = true;
status_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
private void Status_DoWork(object sender, DoWorkEventArgs e)
{
//make call to Logger class getStatus method
_logger.getStatus(sender);
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressbar1.Value = e.ProgressPercentage;
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
return;
}
else
{
Start_button.IsEnabled = true;
}
}
private void Start_button_Click(object sender, RoutedEventArgs e)
{
//initiate status_Worker when button is clicked
status_Worker.RunWorkerAsync();
Start_button.IsEnabled = false;
}
现在在记录器中 class 我有 getStatus() 方法。我调用本地服务器以获取已处理文件的状态和所有工作,我看到值已在我的 MainWindow.Status 上自动更新。
public async Task getStatus(object sender)
{
BackgroundWorker statusWorker = (BackgroundWorker)sender;
//Making a call to ReportProgress here works and it shows the progress bar
//statusWorker.ReportProgress(99);
//REQUEST STATUS from a server
//Status format
//CurrentParser, NumberOfFilesToParse,CountOfCompletedFiles,Status, NumberOfProcessRunning
int CountOfCompletedFiles;
int NumberOfFilesToParse;
int percent;
string status = "Running";
string[] stats;
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
while(status!="Complete")
{
var getstatus = await request.GetStringAsync("http://localhost:8085/status");
logs.Add(getstatus);
stats = getstatus.Split(delimiterChars);
NumberOfFilesToParse = Int32.Parse(stats[1]);
CountOfCompletedFiles = Int32.Parse(stats[2]);
status = stats[3];
Thread.Sleep(1000);
MainWindow.main.Status = "Files to process: " + NumberOfFilesToParse + " Files completed: " + CountOfCompletedFiles + " Status: " + status;
if(NumberOfFilesToParse!=0 && status!="Complete")
{
percent = (CountOfCompletedFiles * 100) / NumberOfFilesToParse;
//a call to ReportProgress here stalls the program at this point
//statusWorker.ReportProgress(percent);
}
}
MainWindow.main.Status = "Completed!";
}
在 getStatus 方法开始时对 ReportProgress 的调用有效,但在我的 while 循环期间或之后对 ReportProgress 的调用导致进程在该点停止。即使使用静态数字 ReportProgress(99) 它也只在开头执行
您的 Status_DoWork
方法是即发即弃。它调用 async Task
方法然后忽略 Task
它 returns.
您 运行 遇到的一个问题是 BackgroundWorker
simply doesn't work with async
. What's actually happening is that as soon as the first await
is reached in getStatus
, it returns an incomplete Task
到 Status_DoWork
,然后退出。这会导致 BackgroundWorker
完成,因此引发进度事件对于 BackgroundWorker
.
不再有意义
The modern replacement for BackgroundWorker
is Task.Run
, which includes support for progress reporting. Ideally, you would only use Task.Run
for CPU-bound methods, not the I/O-bound methods:
private void Start_button_Click(object sender, RoutedEventArgs e)
{
Start_button.IsEnabled = false;
var progress = new Progress<int>(update => progressbar1.Value = update);
try
{
await _logger.getStatus(progress);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
Start_button.IsEnabled = true;
}
}
public async Task getStatus(IProgress<int> progress)
{
int CountOfCompletedFiles;
int NumberOfFilesToParse;
int percent;
string status = "Running";
string[] stats;
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
while(status!="Complete")
{
var getstatus = await request.GetStringAsync("http://localhost:8085/status");
logs.Add(getstatus);
stats = getstatus.Split(delimiterChars);
NumberOfFilesToParse = Int32.Parse(stats[1]);
CountOfCompletedFiles = Int32.Parse(stats[2]);
status = stats[3];
await Task.Run(() => Thread.Sleep(1000)); // process file in Task.Run
MainWindow.main.Status = "Files to process: " + NumberOfFilesToParse + " Files completed: " + CountOfCompletedFiles + " Status: " + status;
if(NumberOfFilesToParse!=0 && status!="Complete")
{
percent = (CountOfCompletedFiles * 100) / NumberOfFilesToParse;
progress.Report(percent);
}
}
MainWindow.main.Status = "Completed!";
}
您好,我正在尝试填充进度条,但 ReportProgress 调用由于某种原因未被执行。
这是我的代码
//create status_Worker
status_Worker = new BackgroundWorker();
status_Worker.DoWork += new DoWorkEventHandler(Status_DoWork);
status_Worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
status_Worker.WorkerReportsProgress = true;
status_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
private void Status_DoWork(object sender, DoWorkEventArgs e)
{
//make call to Logger class getStatus method
_logger.getStatus(sender);
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressbar1.Value = e.ProgressPercentage;
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
return;
}
else
{
Start_button.IsEnabled = true;
}
}
private void Start_button_Click(object sender, RoutedEventArgs e)
{
//initiate status_Worker when button is clicked
status_Worker.RunWorkerAsync();
Start_button.IsEnabled = false;
}
现在在记录器中 class 我有 getStatus() 方法。我调用本地服务器以获取已处理文件的状态和所有工作,我看到值已在我的 MainWindow.Status 上自动更新。
public async Task getStatus(object sender)
{
BackgroundWorker statusWorker = (BackgroundWorker)sender;
//Making a call to ReportProgress here works and it shows the progress bar
//statusWorker.ReportProgress(99);
//REQUEST STATUS from a server
//Status format
//CurrentParser, NumberOfFilesToParse,CountOfCompletedFiles,Status, NumberOfProcessRunning
int CountOfCompletedFiles;
int NumberOfFilesToParse;
int percent;
string status = "Running";
string[] stats;
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
while(status!="Complete")
{
var getstatus = await request.GetStringAsync("http://localhost:8085/status");
logs.Add(getstatus);
stats = getstatus.Split(delimiterChars);
NumberOfFilesToParse = Int32.Parse(stats[1]);
CountOfCompletedFiles = Int32.Parse(stats[2]);
status = stats[3];
Thread.Sleep(1000);
MainWindow.main.Status = "Files to process: " + NumberOfFilesToParse + " Files completed: " + CountOfCompletedFiles + " Status: " + status;
if(NumberOfFilesToParse!=0 && status!="Complete")
{
percent = (CountOfCompletedFiles * 100) / NumberOfFilesToParse;
//a call to ReportProgress here stalls the program at this point
//statusWorker.ReportProgress(percent);
}
}
MainWindow.main.Status = "Completed!";
}
在 getStatus 方法开始时对 ReportProgress 的调用有效,但在我的 while 循环期间或之后对 ReportProgress 的调用导致进程在该点停止。即使使用静态数字 ReportProgress(99) 它也只在开头执行
您的 Status_DoWork
方法是即发即弃。它调用 async Task
方法然后忽略 Task
它 returns.
您 运行 遇到的一个问题是 BackgroundWorker
simply doesn't work with async
. What's actually happening is that as soon as the first await
is reached in getStatus
, it returns an incomplete Task
到 Status_DoWork
,然后退出。这会导致 BackgroundWorker
完成,因此引发进度事件对于 BackgroundWorker
.
The modern replacement for BackgroundWorker
is Task.Run
, which includes support for progress reporting. Ideally, you would only use Task.Run
for CPU-bound methods, not the I/O-bound methods:
private void Start_button_Click(object sender, RoutedEventArgs e)
{
Start_button.IsEnabled = false;
var progress = new Progress<int>(update => progressbar1.Value = update);
try
{
await _logger.getStatus(progress);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
Start_button.IsEnabled = true;
}
}
public async Task getStatus(IProgress<int> progress)
{
int CountOfCompletedFiles;
int NumberOfFilesToParse;
int percent;
string status = "Running";
string[] stats;
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
while(status!="Complete")
{
var getstatus = await request.GetStringAsync("http://localhost:8085/status");
logs.Add(getstatus);
stats = getstatus.Split(delimiterChars);
NumberOfFilesToParse = Int32.Parse(stats[1]);
CountOfCompletedFiles = Int32.Parse(stats[2]);
status = stats[3];
await Task.Run(() => Thread.Sleep(1000)); // process file in Task.Run
MainWindow.main.Status = "Files to process: " + NumberOfFilesToParse + " Files completed: " + CountOfCompletedFiles + " Status: " + status;
if(NumberOfFilesToParse!=0 && status!="Complete")
{
percent = (CountOfCompletedFiles * 100) / NumberOfFilesToParse;
progress.Report(percent);
}
}
MainWindow.main.Status = "Completed!";
}