Почему у меня есть возможность * не * вызывать Concurrency::agent::done внутри run?
Это в контексте API параллелизма Microsoft C++.
Есть класс под названием agent
(под Concurrency
пространство имен), и это в основном конечный автомат, который вы получаете и реализуете чисто виртуальный agent::run
,
Теперь вы обязаны позвонить agent::start
, который переведет его в работоспособное состояние. Вы тогда звоните agent::wait
* или любой из его вариантов, чтобы фактически выполнить agent::run
метод.
Но почему мы должны позвонить agent::done
в теле? Я имею в виду, очевидный ответ заключается в том, что agent::wait
* будет ждать пока сигнал о готовности не истечет или не истечет время ожидания, но...
Что хотели дизайнеры? Почему бы не сделать так, чтобы агент вошел в состояние готовности agent::run
возвращается? Это то, что я хочу знать. Почему у меня есть возможность не звонить done
? Методы ожидания генерируют исключения, если истекло время ожидания.
1 ответ
Единственная причина, по которой я вижу, состоит в том, что это позволит вам заявить, что вы 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 */ }
};
... / пожимает плечами