2

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?

kring
  • 246
  • 1
  • 3

0 Answers0