4

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

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

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

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

设计师的意图是什么?为什么代理agent::run返回时不进入完成状态?这就是我想知道的。为什么我可以选择不打电话done?如果超时已过,wait 方法会抛出异常。

4

1 回答 1

2

我能看到的唯一原因是它会让你声明你是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 */ }
};

... /耸耸肩

于 2012-11-16T19:14:35.583 回答