Consider the following pattern:
We have a timer that fires every N seconds. The purpose of this timer is to execute a task (A) that generates new task (B). B's purpose is to calculate some new data, but may take a long time to complete. A stores the task B into some internal state of the class.
Now a task C will be called by the caller of the class and will need the result calculated by task B. Therefore, it waits on task B by doing a continuation. Now, we can see that we have two tasks that can run in parallel with each other and both can modify or access the task B variable stored in the class.
So the question is this: is it safe to do this? What are the semantics? What if task B assigns a new task to the member variable at the same time that task C tries to wait on it? What if C is already waiting on it when it happens?
In pseudo code, it might look like something like:
We have a timer that fires every N seconds. The purpose of this timer is to execute a task (A) that generates new task (B). B's purpose is to calculate some new data, but may take a long time to complete. A stores the task B into some internal state of the class.
Now a task C will be called by the caller of the class and will need the result calculated by task B. Therefore, it waits on task B by doing a continuation. Now, we can see that we have two tasks that can run in parallel with each other and both can modify or access the task B variable stored in the class.
So the question is this: is it safe to do this? What are the semantics? What if task B assigns a new task to the member variable at the same time that task C tries to wait on it? What if C is already waiting on it when it happens?
In pseudo code, it might look like something like:
void TaskA()
{
// Run every N seconds
m_TaskB = pplx::create_task(&TaskB); // TaskA assigns m_TaskB
}
void TaskB()
{
// Do some stuff
m_SomeData = /* some data */;
}
void TaskC()
{
m_TaskB.then([this](pplx::task<void> t) // TaskC waits on m_TaskB.
{
t.get(); // Force throw an exception if previous task failed. All callers who are waiting on this task will be fed this exception.
return m_SomeData;
});
}
TaskB does not return any data because it mutates class variables.