Почему у меня есть возможность * не * вызывать Concurrency :: agent :: done внутри run?

Это в контексте API параллелизма Microsoft C ++.

Есть класс под названием agent (под Concurrency пространство имен), и это в основном конечный автомат, который вы получаете и реализуете чисто виртуальный agent::run,

Теперь вы обязаны позвонить agent::start, который поместит его в работоспособный государство. Вы тогда звоните agent::wait* или любой из его вариантов, чтобы фактически выполнить agent::run метод.

Но почему мы должны позвонить agent::done в теле? Я имею в виду, очевидный ответ заключается в том, что agent::wait* будет ждать пока сигнал о готовности не истечет или не истечет время ожидания, но …

Что хотели дизайнеры? Почему бы не сделать так, чтобы агент перешел в состояние готовности? agent::run возвращается? Это то, что я хочу знать. Почему у меня есть возможность не звонить done? Методы ожидания генерируют исключения, если время ожидания истекло.

4

Решение

Единственная причина, по которой я вижу это то, что она позволяет вам заявить, что вы 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 */ }
};

… / пожимание плечами

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]