VC++ 2015 – Lazy generators

If you have ever used iterators in C# or Visual Basic, then this is essentially the same thing. You would need to enable the new experimental /await compiler option, same as in the previous blog entry.

std::experimental::generator<int> evens(size_t count)
{
  using namespace std::chrono;

  for (size_t i = 1; i <= count; i++)
  {
    yield i * 2;
    std::cout << "yielding..." << std::endl;
    std::this_thread::sleep_for(1s);
  }
}

Calling this method would be fairly straightforward.

void main_yield()
{
  for (auto ev : evens(7))
  {
    std::cout << ev << std::endl;
  }
}

And here’s the expected output.

yield_demo_cpp

I added the console output to demonstrate the laziness of the generator.

VC++ 2015 – Using resumable functions

Visual C++ 2015 has a new compiler option called /await that can be used to write and call resumable functions. Do note that this is an experimental feature and even the associated headers are in an experimental sub-directory. There is no UI option to turn this compiler option in VS 2015, so you would need to manually add it via the Additional Options box under the C/C++ property page.

To compile the samples in this blog entry, you would need the following includes.

#include <thread>
#include <future>
#include <iostream>
#include <experimental\resumable>
#include <experimental\generator>

Here’s a simple example async method that sums two numbers. To demonstrate the async-nature of the call, I’ve added a sleep of 2 seconds to slow down the operation.

std::future<int> sum_async(int x, int y)
{
  using namespace std::chrono;

  return std::async([x, y] 
  {
    std::this_thread::sleep_for(2s);
    return x + y; 
  });
}

The async function will execute the function asynchronously, typically in a separate thread, and return a future that will hold the result of the call when it’s completed. Now, here’s how this method can be called.

std::future<void> call_sum_async(int x, int y)
{
  std::cout << "** async func - before call" << std::endl;
  auto sum = await sum_async(x, y);
  std::cout << "** async func - after call" << std::endl;
}

The await keyword calls that method asynchronously and waits until the method executes to completion. And then control goes to the next line of code. At least in the version of VC++ 2015 I tested this on, if you use await, the return type needs to be a future.

Now, here’s a calling method that invokes this caller method.

void main_async()
{
  std::cout << "<< main func - before call" << std::endl;
  auto result = call_sum_async(7, 9);
  std::cout << "<< main func - after call" << std::endl;

  {
    using namespace std::chrono;
    std::cout << "<< main func - before sleep" << std::endl;
    std::this_thread::sleep_for(3s);
    std::cout << "<< main func - after sleep" << std::endl;
  }

  result.get();
  std::cout << "<< main func - after get" << std::endl;
}

To show that the async method actually does execute asynchronously, I added a sleep block in the calling method. Here’s what the output looks like.

async_demo_cpp

Notice how the calling method continues to execute. And then once the async method has completed it returns control back to the main thread. The await keyword just makes it so easy to do this. You write your code just as you would write synchronous code, and all the async-ness is hidden from you. Well not really hidden, but handled for you smoothly.

Oh by the way, I am back to blogging after a bit of a hiatus. Expect to see me post far more frequently going forward.