Reputation: 286
The Concurrency Runtime detects when exceptions thrown by tasks cannot be handled and "fails fast"; that is, it terminates the process. I have a case where multiple sub-tasks given to a when_all
may throw exceptions. Ideally, I'd like these exceptions to cancel the task tree and then be aggregated in a single exception that is raised in the top-level get or wait. Instead, my process gets terminated out from under me. Here's a toy example that demonstrates the problem:
#include <tchar.h>
#include <ppltasks.h>
#include <iostream>
#include <vector>
concurrency::task<int> CreateTask(int i)
{
return concurrency::create_task([i]()
{
throw std::runtime_error("boo");
return i;
});
}
void Go()
{
std::vector<concurrency::task<int>> tasks;
tasks.push_back(CreateTask(1));
tasks.push_back(CreateTask(2));
auto allDone = concurrency::when_all(tasks.begin(), tasks.end());
try
{
allDone.get();
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
}
catch (...)
{
std::cout << "Unexpected exception." << std::endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Go();
std::cout << "Process is still running." << std::endl;
return 0;
}
In this example, the process is terminated before "Process is still running" is printed to the console. It seems that an exception in a sub-task causes wait_all
to invoke its continuation immediately, without waiting for the other sub-tasks to finish/cancel, and then an exception raised by other sub-tasks cannot be handled and causes the process to terminate. This seems hugely undesirable. Is there a workaround? Is this a bug? Am I missing something?
Upvotes: 4
Views: 216