【问题标题】:How to know how many tasks are already completed?如何知道已经完成了多少任务?
【发布时间】:2019-12-07 08:24:25
【问题描述】:

在 C++ Builder 10.3.3 中,我使用以下测试代码:

int count = 500;
 _di_ITask* task = new _di_ITask[count];
ProgressBar1->Position = 0;
for(int i = 0; i < count; i++){
    task[i] = TTask::Create([i, this](){
        // do something...
        Sleep(10);
    });
    task[i]->Start();
    //ProgressBar1->Position = numberOfFinishedTasks;
    //Application->ProcessMessages();
}
TTask::WaitForAll(task, count - 1);

在这种情况下,有 500 个测试任务,我希望我的 ProgressBar 组件显示当前已完成任务的数量。我不知道如何获得该信息。谢谢!

【问题讨论】:

  • 在每个任务结束时增加一个原子计数器?
  • @AlanBirtles 问题是如何获取这些信息。
  • @Tracer 每个任务都必须“报告”我已完成,例如增加一个原子计数器。 (然后触发重绘左右)
  • 但是……您自己创建这些任务。不能在Sleep(10)之后插入吗?
  • @Dima TTask 是 Embarcadero 的 Parallel Programming Library 的一部分。

标签: delphi c++builder


【解决方案1】:

最简单的解决方案是让 lambda 本身在退出之前更新 ProgressBar。为此,您可以使用TThread::Synchronize() 或TThread::Queue()。

问题是,TTask::WaitForAll() 是一种阻塞方式,根本不抽主 UI 消息队列,所以 Synchronize()/Queue() 请求根本不会被处理。您可以通过在具有超时的循环中调用 WaitForAll() 来解决此问题,以便循环可以根据需要泵送消息。

试试这样的:

int count = 500;
std::vector<_di_ITask> task(count);

ProgressBar1->Position = 0;
ProgressBar1->Min = 0;
ProgressBar1->Max = count;
ProgressBar1->Step = 1;

for(int i = 0; i < count; ++i){
    task[i] = TTask::Create(
        [i, this](){
            // do something...
            TThread::Queue(nullptr, ProgressBar1->StepIt);
        }
    );
    task[i]->Start();
}

while (!TTask::WaitForAll(task.data(), count - 1, 1000)){
    Application->ProcessMessages();
}

【讨论】:

  • 像魅力一样工作!你是一个真正的救世主雷米 :) 谢谢。
  • YouTube 视频中详细解释了类似的方法:“C++ Builder - Parallel Library vs. TThread”youtube.com/watch?v=rTf7m1jVcbY
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 2020-01-29
  • 2020-02-06
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
相关资源
最近更新 更多