为什么我可以选择*不*调用并发::代理::d一个内部运行

Why do I have the option to *not* call Concurrency::agent::done inside run?

本文关键字:一个 运行 内部 代理 选择 我可以 调用 为什么 并发      更新时间:2023-10-16

这是在Microsoft C++并发 API 的上下文中。

有一个名为 agent 的类(在命名空间下Concurrency),它基本上是您派生和实现纯虚拟agent::run的状态机。

现在,您有责任调用 agent::start ,这将使它处于可运行状态。然后调用 agent::wait * 或其任何变体来实际执行 agent::run 方法。

但是,为什么我们必须在体内称agent::done呢?我的意思是,显而易见的答案是 agent::wait * 将等到发出完成信号或超时已过,但是......

设计师的意图是什么?为什么不让代理在返回时进入完成状态agent::run?这就是我想知道的。为什么我可以选择不拨打done?如果超时已过,等待方法将引发异常。

我能看到的唯一原因是它会让你声明你done(),然后做更多你不希望你的消费者不得不等待的工作(比如清理)。

现在,他们本可以这样做:

private: void agent::do_run() {
  run();
  if (status() != agent_done)
    done();
}

然后让他们的框架调用do_run()而不是直接run()(或等效的)。

但是,您会注意到您自己可以做到这一点。

class myagent: public agent {
protected:
  virtual void run() final override { /* see do_run above, except call do_run in it */ }
  virtual void do_run() = 0;
};

噗,如果你的do_run()无法调用done(),包装函数会为你做这件事。 如果第二个虚拟功能开销对您来说太高:

template<typename T>
class myagent: public agent {
private:
  void call_do_run()
  {
    static_cast<T*>(this)->do_run();
  }
protected:
  virtual void run() final override { /* see do_run above, but call_do_run() */ }
};

允许您执行编译时调度的 CRTP。 用:

class foo: public myagent<foo>
{
public:
  void do_run() { /* code */ }
};

。。。/耸肩