c++/cli using IProgress in Task



我在c++/cli应用程序中使用任务来管理一些耗时的操作,而不需要冻结UI,作为BackgroundWorker的替代品。这是基本用法:

WorkArguments ^arguments = gcnew WorkArguments(
        //some argument objects as contructor parameters
);
Task::Factory->StartNew(gcnew Action<Object^>(this, &myForm::doSomeWork), arguments);        
void myForm::doSomeWork(Object ^arguments) {
 //doing some stuff
}

到目前为止,一切顺利。我现在的问题是,我不知道如何使用IProgress接口将完成工作的报告提供给我的UI。我找不到方法来声明一个与StartNew()兼容的委托,它可以获得IProcess对象。

我发现最接近的东西是AsyncInfo::Run<TProgress> Method (Func<CancellationToken, IProgress<TProgress>, Task>),虽然我不确定这是预期的用途,但我没有尝试过,因为我不太确定它的用途,

我应该添加IProgress实例到我的WorkArguments类吗?

使用System::Progress<T>类,这是IProgress的一个常用实现。如果你只想报告进度,你所需要的一切。

它确实有一个缺失的手册,它有令人不快的故障模式,如果你不正确使用它。第一个要求是必须在UI线程上创建类的实例,不能在工作线程中这样做。在启动任务之前将其存储在类的字段中,以便worker可以使用它。这是必要的,以便它可以确定应该在哪个线程上引发ProgressChanged事件。

并且您必须小心不要太频繁地调用Report()。限制在每50毫秒左右不超过一次。高频率地调用它(每秒超过1000次)将使UI线程陷入停顿,并导致它停止更新UI和响应输入。当你只在报告的进度值实际发生变化并且进度范围有限(如0-100%)时调用它时,通常很容易避免。

最新更新