我目前有以下内容:
查看模型
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();
worker_ProgressChanged
void worker_ProgressChanged(object sender,ProgressChangedEventArgs e) { CurrentProgress = e.ProgressPercentage; }
在我的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); } }
第二次调用ReportProgress(x)时,我收到错误:
此操作已经调用了OperationCompleted,并且进一步调用是非法的.
CurrentProgress绑定到我的XAML
<ProgressBar Minimum="0" Maximum="{Binding MaxValueProgressBar}" Value="{Binding CurrentProgress,Mode=OneWay}" />
有人会对这里可能发生的事情有任何想法吗?
解决方法
详细说明dkozl的评论:
异步可能导致问题.您发布的代码中没有任何内容会导致问题,但当然您发布的代码示例远非完整.
如果在processMovie_DoWork()方法中有一个await语句(这是使方法异步的通常原因),那么该方法只会执行到第一个await语句的点,然后它将退出.
就BackgroundWorker类而言,这标志着工作的结束.它无法知道会调用某些延续.因此,当您调用ReportProgress()方法时,该操作实际上已完成,使对ReportProgress()的调用非法.
你有几个选择:
>摆脱await语句并同步执行这些操作.最好通过调用API的同步版本.
>摆脱BackgroundWorker,直接调用processMovie_DoWork()方法(尽管可能已重命名为其他方法).在这种情况下,您只需直接更新CurrentProgress属性,而不是调用ReportProgress()方法.
恕我直言,第二种选择更为可取.您可以简单地等待您的processMovie_DoWork()方法,并避免处理BackgroundWorker的所有麻烦.