“操作已完成";使用进度栏时出现错误 [英] "Operation already completed" error when using Progress Bar

查看:57
本文介绍了“操作已完成";使用进度栏时出现错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有以下内容:

查看模型

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.

您在这里有两个选择:

  1. 摆脱 await 语句,并同步执行这些操作.最好通过调用API的同步版本.
  2. 摆脱 BackgroundWorker ,而直接调用您的 processMovie_DoWork()方法(尽管可能已重命名为其他名称).在这种情况下,您无需直接调用 ReportProgress()方法,而只需直接更新 CurrentProgress 属性即可.
  1. Get rid of the await statements and perform those operations synchronously. Preferably by calling the synchronous version of the API.
  2. Get rid of the BackgroundWorker and just call your processMovie_DoWork() method directly (albeit likely renamed to something else). In this case, instead of calling the ReportProgress() method, you'd just update the CurrentProgress 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆