wpf 使用进度条时出现“操作已完成”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28230363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"Operation already completed" error when using Progress Bar
提问by Peter Duniho
I currently have the following:
我目前有以下几点:
View Model
查看模型
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
worker_ProgressChanged
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
CurrentProgress = e.ProgressPercentage;
}
In my MovieProcessorclass, I have the method processMovie_DoWork.
在我的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);
}
}
The second timeReportProgress(x)is called, I get the error:
在第二次ReportProgress(x)被调用时,我得到的错误:
This operation has already had OperationCompleted called on it and further calls are illegal.
This operation has already had OperationCompleted called on it and further calls are illegal.
CurrentProgressis bound to my XAML
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?
有没有人知道这里可能发生什么?
回答by Peter Duniho
To elaborate on the comment from dkozl:
详细说明 dkozl 的评论:
It is possible that the asyncis 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.
可能async是导致问题的原因。您发布的代码中没有任何内容会导致问题,但当然您发布的代码示例还远未完成。
If you have an awaitstatement 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 awaitstatement, and then it will exit.
如果您的方法中有一条await语句processMovie_DoWork()(这是创建方法的常见原因async),那么该方法将只执行到第一个await语句的位置,然后它就会退出。
As far as the BackgroundWorkerclass 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.
就BackgroundWorker班级而言,这标志着工作的结束。它无法知道会调用某个延续。因此,当您调用该ReportProgress()方法时,操作实际上已经完成,从而使调用ReportProgress()非法。
You have a couple of options here:
您在这里有几个选择:
- Get rid of the
awaitstatements and perform those operations synchronously. Preferably by calling the synchronous version of the API. - Get rid of the
BackgroundWorkerand just call yourprocessMovie_DoWork()method directly (albeit likely renamed to something else). In this case, instead of calling theReportProgress()method, you'd just update theCurrentProgressproperty directly.
- 摆脱
await语句并同步执行这些操作。最好通过调用 API 的同步版本。 - 摆脱
BackgroundWorker并直接调用您的processMovie_DoWork()方法(尽管可能重命名为其他方法)。在这种情况下,ReportProgress()您只需CurrentProgress直接更新属性,而不是调用该方法。
IMHO, the second option is much preferable. You can simply awaityour processMovie_DoWork()method, and avoid all the hassle of dealing with BackgroundWorker.
恕我直言,第二种选择更可取。您可以简单地使用await您的processMovie_DoWork()方法,并避免处理BackgroundWorker.
回答by Anis Tissaoui
I just encountered this problem trying to poll status from a Web API using Background Worker.
I resolved this by removing asyncand changing the awaitoperator to Task.Wait()and it worked perfectly.
我刚刚在尝试使用后台工作器从 Web API 轮询状态时遇到了这个问题。我通过删除操作符并将其async更改为await来解决此问题,Task.Wait()并且它运行良好。
Here is my Code in place of "// Do stuff like calling API" :
这是我的代码代替“ // Do stuff like calling API”:
var task = JobManager.GetJobStatus(id);
task.Wait();
var status = task.Result;
I hope this helps somebody else. I am sure you got over this issue.
我希望这对其他人有帮助。我相信你已经解决了这个问题。

