使用进度条时"操作已完成"错误

11 c# wpf backgroundworker progress-bar

我目前有以下内容:

查看模型

MovieProcessor movieProcessor = new MovieProcessor(SelectedPath, this);

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += movieProcessor.processMovie_DoWork;
worker.ProgressChanged += worker_ProgressChanged;

progressBar.Show();
worker.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)

worker_ProgressChanged

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
  CurrentProgress = e.ProgressPercentage;
}
Run Code Online (Sandbox Code Playgroud)

在我的MovieProcessor班上,我有方法processMovie_DoWork.

public async void processMovie_DoWork(object sender, DoWorkEventArgs e)
{
    for (int x = 0; x < totalFilesToProcess; ++x)
    {
         // Do stuff like calling API

         (sender as BackgroundWorker).ReportProgress(x);

    }
}
Run Code Online (Sandbox Code Playgroud)

第二次 ReportProgress(x)被调用时,我得到的错误:

This operation has already had OperationCompleted called on it and further calls are illegal.

CurrentProgress 是我的约束 XAML

<ProgressBar  Minimum="0" Maximum="{Binding MaxValueProgressBar}"  Value="{Binding CurrentProgress, Mode=OneWay}" />
Run Code Online (Sandbox Code Playgroud)

有人会对这里可能发生的事情有任何想法吗?

Pet*_*iho 13

详细说明dkozl的评论:

这可能async导致问题.您发布的代码中没有任何内容会导致问题,但当然您发布的代码示例远非完整.

如果你的方法中有一个await语句processMovie_DoWork()(这是一个方法的通常原因async),那么该方法只会执行到第一个await语句的点,然后它将退出.

BackgroundWorker课程而言,这标志着工作的结束.它无法知道会调用某些延续.因此,当您调用该ReportProgress()方法时,该操作实际上已完成,使该调用ReportProgress()非法.

你有几个选择:

  1. 摆脱await语句并同步执行这些操作.最好通过调用API的同步版本.
  2. 摆脱BackgroundWorker并直接调用您的processMovie_DoWork()方法(虽然可能重命名为其他东西).在这种情况下,ReportProgress()您只需CurrentProgress直接更新属性,而不是调用该方法.

恕我直言,第二种选择更为可取.你可以简单地使用await你的processMovie_DoWork()方法,并避免处理所有麻烦BackgroundWorker.


Ani*_*oui 7

我刚刚在尝试使用后台工作程序从 Web API 轮询状态时遇到了这个问题。我通过删除async并更改await操作符来解决这个问题Task.Wait(),它工作得很好。

这是我的代码代替“ // Do stuff like calling API”:

var task = JobManager.GetJobStatus(id);
task.Wait();
var status = task.Result;
Run Code Online (Sandbox Code Playgroud)

我希望这对其他人有帮助。我相信你已经解决了这个问题。