“操作已完成";使用进度栏时出现错误 [英] "Operation already completed" error when using 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();
worker_ProgressChanged
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
CurrentProgress = e.ProgressPercentage;
}
在我的 MovieProcessor
类中,我有方法 processMovie_DoWork
.
In my MovieProcessor
class, I have the method 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}" />
有人会对这里发生的事情有任何想法吗?
Would anyone have any idea as to what might be happening here?
推荐答案
详细说明dkozl的评论:
To elaborate on the comment from dkozl:
async
可能是导致此问题的原因.您发布的代码中没有什么会引起问题的,但是您发布的代码示例当然还远远不够完整.
It is possible that the async
is causing the problem. There's nothing in the code you posted that would cause an issue, but of course the code example you posted is far from complete.
如果您的 processMovie_DoWork()
方法中有一个 await
语句(这是使方法 async
的常见原因),则该方法将只执行到第一个 await
语句的点,然后退出.
If you have an await
statement in your processMovie_DoWork()
method (which is the usual reason one makes a method async
), then the method will execute only as far as the point of the first await
statement, and then it will exit.
就考虑 BackgroundWorker
类而言,这标志着工作的结束.它没有办法知道会调用某些继续.因此,当您调用 ReportProgress()
方法时,该操作实际上已经完成,因此对 ReportProgress()
的调用是非法的.
As far as the BackgroundWorker
class is considered, this marks the end of the work. It has no way to know that some continuation would be called. Thus, when you call the ReportProgress()
method, the operation has in fact completed, making the call to ReportProgress()
illegal.
您在这里有两个选择:
- 摆脱
await
语句,并同步执行这些操作.最好通过调用API的同步版本. - 摆脱
BackgroundWorker
,而直接调用您的processMovie_DoWork()
方法(尽管可能已重命名为其他名称).在这种情况下,您无需直接调用ReportProgress()
方法,而只需直接更新CurrentProgress
属性即可.
- Get rid of the
await
statements and perform those operations synchronously. Preferably by calling the synchronous version of the API. - Get rid of the
BackgroundWorker
and just call yourprocessMovie_DoWork()
method directly (albeit likely renamed to something else). In this case, instead of calling theReportProgress()
method, you'd just update theCurrentProgress
property directly.
恕我直言,第二种选择更可取.您只需 await
您的 processMovie_DoWork()
方法,就可以避免处理 BackgroundWorker
的所有麻烦.
IMHO, the second option is much preferable. You can simply await
your processMovie_DoWork()
method, and avoid all the hassle of dealing with BackgroundWorker
.
这篇关于“操作已完成";使用进度栏时出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!