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

This is in the context of the Microsoft C ++ Concurrency API.

There is a class called agent (in the Concurrency namespace), and basically it is a state machine that you create and implement a pure virtual agent::run .

Now you are responsible for calling agent::start , which puts it in runnable state. Then you call agent::wait * or any of its variants to actually execute the agent::run method.

But why should we call agent::done inside the body? I mean, the obvious answer is that agent::wait * will wait until the timeout is written or expires, but ...

What were the designers like? Why not turn the agent on when agent::run returns? This is what I want to know. Why do I have the opportunity not to call done ? Waiting methods throw an exception if the timeout has passed.

+4
source share
1 answer

The only reason I see is that it will let you indicate that you are done() , then do more work (like cleaning) that you don't want your consumer to have to wait.

Now they could do this:

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

then their do_run() -frame call do_run() instead of run() directly (or the equivalent).

However, you will notice that you can do it yourself.

 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; }; 

and poof, if your do_run() cannot call done() , the wrapping function will do it for you. If this second overhead utility function is too high for you:

 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, which allows sending at compile time. Using:

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

... / shrug

+2
source

Source: https://habr.com/ru/post/1446514/


All Articles