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 TaskStatus_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!";
}