0 Comments Posted in:

Suppose in C# we have a number of tasks to perform that we're currently doing sequentially, but would like to speed up by running them in parallel. As a trivial example, imagine we're downloading a bunch of web pages like this:

var urls = new [] { 
var client = new HttpClient();
foreach(var url in urls)
    var html = await client.GetStringAsync(url);
    Console.WriteLine($"retrieved {html.Length} characters from {url}");

To parallelize this, we could just turn every single download into a separate Task with Task.Run and wait for them all to complete, but what if we wanted to limit the number of concurrent downloads? Let's say we only want 4 downloads to happen at a time.

In this trivial example, the exact number might not matter too much, but it's not hard to imagine a situation in which you would want to avoid too many concurrent calls to a downstream service.

In this post I'll look at four different ways of solving this problem.

Technique 1 - ConcurrentQueue

The first technique has been my go-to approach for many years. The basic idea is to put the work onto a queue and then have multiple threads reading off that queue. This is a nice simple approach but it does require us to remember to lock the queue as it will be accessed by multiple threads. In this example I'm using ConcurrentQueue to give us thread safety.

We fill the queue with all the urls to download, and then start one Task for each thread that simply sits in a loop trying to read from the queue, and exits when there are no more items left in the queue. We put each of these queue reader tasks in a list and then use Task.WhenAll to wait for them all to exit, which will happen once the final download has completed.

var maxThreads = 4;
var q = new ConcurrentQueue<string>(urls);
var tasks = new List<Task>();
for(int n = 0; n < maxThreads; n++)
    tasks.Add(Task.Run(async () => {
        while(q.TryDequeue(out string url)) 
            var html = await client.GetStringAsync(url);
            Console.WriteLine($"retrieved {html.Length} characters from {url}");
await Task.WhenAll(tasks);

I still like this approach as its conceptually simple. But it can be a bit of a pain if we are still generating more work to do while we've started processing work as the reader threads could exit too early.

Technique 2 - SemaphoreSlim

Another approach (inspired by this StackOverflow answer) to use a SemaphoreSlim with an initialCount equal to the maximum number of threads. Then you use WaitAsync to wait until it's OK to queue up another. So immediately we kick off four tasks, but then have to wait for the first of those to finish before we get past WaitAsync to add the next.

var allTasks = new List<Task>();
var throttler = new SemaphoreSlim(initialCount: maxThreads);
foreach (var url in urls)
    await throttler.WaitAsync();
        Task.Run(async () =>
                var html = await client.GetStringAsync(url);
                Console.WriteLine($"retrieved {html.Length} characters from {url}");
await Task.WhenAll(allTasks);

The code here is a bit more verbose than the ConcurrentQueue approach and also ends up with a potentially huge list containing mostly completed Tasks, but this approach does have an advantage if you are generating the tasks to be completed at the same time you are executing them.

For example, to upload a large file to Azure blob storage you might read 1MB chunks sequentially, but want to upload up to four in parallel. You don't want to read all the chunks in advance of uploading them as that uses a lot of time and memory before we can even start uploading. With this approach we can generate the work to be done just in time, as threads become available for uploading which is more efficient.

Technique 3 - Parallel.ForEach

The Parallel.ForEach method at first appears to be the perfect solution to this problem. You can simply specify the MaxDegreeOfParallelism and then provide an Action to perform on each item in your IEnumerable:

var options = new ParallelOptions() { MaxDegreeOfParallelism = maxThreads };
Parallel.ForEach(urls, options, url =>
        var html = client.GetStringAsync(url).Result;
        Console.WriteLine($"retrieved {html.Length} characters from {url}");

Looks nice and simple doesn't it? However, there is a nasty gotcha here. Because Parallel.ForEach takes an Action, not a Func<T> it should only be used to call synchronous functions. You might notice we've ended up putting a .Result after GetStringAsync which is a dangerous antipattern.

So unfortunately, this method should only be used if you have a synchronous method you want to perform in parallel. There is a NuGet package that implements an asynchronous version of Parallel.ForEach so you could try that if you'd like to write something like this instead:

await uris.ParallelForEachAsync(
    async url =>
        var html = await httpClient.GetStringAsync(url);
        Console.WriteLine($"retrieved {html.Length} characters from {url}");
    maxDegreeOfParalellism: maxThreads);

Technique 4 - Polly Bulkhead Policy

The final technique is to use the "Bulkhead" isolation policy from Polly. A bulkhead policy restricts the number of concurrent calls that can be made, and optionally allows you to queue up calls that exceed that number.

Here we set up a bulkhead policy with a constrained number of concurrent executions and an unlimited number of queued tasks. Then we simply call ExecuteAsync repeatedly on the bulkhead policy, allowing it to either run it immediately or queue it up if too many.

    var bulkhead = Policy.BulkheadAsync(maxThreads, Int32.MaxValue);
    var tasks = new List<Task>();
    foreach (var url in urls)
        var t = bulkhead.ExecuteAsync(async () =>
            var html = await client.GetStringAsync(url);
            Console.WriteLine($"retrieved {html.Length} characters from {url}");
    await Task.WhenAll(tasks);

As with several other of our solutions we put the tasks into a list and use Task.WhenAll to wait for them. It is worth pointing out though, that this pattern is really designed for the situation where concurrent tasks are being generated from multiple threads (for example from ASP.NET controller actions). They simply use a shared bulkhead policy and then you just run a task with await bulkhead.ExecuteAsync(...). So this approach is very straightforward to use in the situations it is designed for.


Parallelism can greatly speed up the overall performance of your application, but when misused can cause more problems than it solves. These patterns allow you to use a constrained number of threads to work through a batch of jobs. The one you should pick depends on the way you're generating tasks - do you know them all up front, or are they created on the fly while you're already processing earlier tasks? And are you generating these tasks sequentially on a single thread, or are multiple threads able to produce additional work items on the fly?

Of course, I'm sure there are plenty of other clever ways of approaching this problem, so do let me know in the comments what your preffered solution is.

0 Comments Posted in:

Azure Functions allows you to protect access to your HTTP triggered functions by means of authorization keys. For each function you can choose an "authorization level". anonymous means no API key is required, function means a function specific API key is required. So in this case each function has its own keys. And admin means you are required to provide the special "master" host key, which is a single key that can be used to call any function in your function app.

To call a protected function you either provide the key as a query string parameter (in the form code=<API_KEY>) or you can provide it as a HTTP x-functions-key header.

Accessing and managing keys in the portal

The Azure portal makes it nice and simple to discover the values these keys. First of all, if we navigate to any function in the portal, you'll see a "Get Function URL" link:


When we click it, it constructs the URL we need to call including the code query string parameter. This dialog also lets us access values for both types of key - the "function" keys specific to this function, and the "host" keys that can be used on all functions, including the special "_master" host key. You can read more about these key types here.


We can manage the keys for an individual function by heading into the "manage" tab for that function:


In here we get the ability to view, renew or revoke each individual function key as well as the host keys. You can create multiple function or host keys, which is great as it allows you to provide separate keys to every client you want to grant access to your function, or to implement key cycling.


Using the key management API

Now although its very convenient to manage keys in the portal, before long you'll probably want to manage these values programatically, and that's where things get a little bit tricky. There is a key management API which allows you to access the values of keys as well as to generate new ones, delete keys, or update them with new auto-generated actions.

This is ideal if you want to automate the deployment of your function app and programatically discover the keys you need to call the functions, but I quickly ran into a problem. How do you authorize calls to this API? I was familiar with authorizing calls to the Kudu API, which requires you to pass the deployment user and password in a basic auth header. I showed how to do this in a post I wrote a while back on deploying web apps with the kudu zipdeploy API.

But unfortunately, this technique doesn't work for the key management API. I eventually stumbled across a GitHub issue that led me to the answer, so I thought I'd document my solution.

Getting the credentials to access the key management API is a two step process. The first step is calling the Kudu API, calling the api/functions/admin/token endpoint which provides us with a token (a JWT), that we can use as a bearer token to call the key management API.

I'm using the Azure CLI and Powershell, but these techniques could be adapted to whatever language or scripting tool you're using.

The first step is that we need to get the credentials to call the Kudu API. If you're authenticated with the Azure CLI, you can do that by calling the az webapp deployment list-publishing-profiles command and extracting the userName and userPWD for MSDeploy. You need to provide the function app name and resource group name.

The username and password are the ones you can get from the portal by downloading the "publish profile" for your function app. My powershell function also converts the user name and password into a base 64 encoded string in the right format to be used as a basic auth header.

function getKuduCreds($appName, $resourceGroup)
    $user = az webapp deployment list-publishing-profiles -n $appName -g $resourceGroup `
            --query "[?publishMethod=='MSDeploy'].userName" -o tsv

    $pass = az webapp deployment list-publishing-profiles -n $appName -g $resourceGroup `
            --query "[?publishMethod=='MSDeploy'].userPWD" -o tsv

    $pair = "$($user):$($pass)"
    $encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
    return $encodedCreds

OK, now we have the credentials we need to call Kudu, we can use this information to call the functions/admin/token endpoint. So my next powershell function uses these credentials in a basic authorization header to get a JWT token we can use as a bearer token.

Then it uses that bearer token to call the key management API, on the admin/functions/<FUNCTION_NAME>/keys endpoint to retrieve all the keys for a specific function. I'm just picking out the first key in this example, but you could do something more elaborate if you wanted to access a key by name. Note that unlike the Kudu APIs, which are at https://<YOUR_APP_NAME>.scm.azurewebsites.net, this API is hosted by the Azure Functions runtime itself, so you find it at https://<YOUR_APP_NAME>.azurewebsites.net

function getFunctionKey([string]$appName, [string]$functionName, [string]$encodedCreds)
    $jwt = Invoke-RestMethod -Uri "https://$appName.scm.azurewebsites.net/api/functions/admin/token" -Headers @{Authorization=("Basic {0}" -f $encodedCreds)} -Method GET

    $keys = Invoke-RestMethod -Method GET -Headers @{Authorization=("Bearer {0}" -f $jwt)} `
            -Uri "https://$appName.azurewebsites.net/admin/functions/$functionName/keys" 

    $code = $keys.keys[0].value
    return $code

With all these pieces in place, we are now in a position to put them together to get the authorization key for a specific function in our application:

$appName = "myapp"
$functionName = "myfunc"
$resourceGroup = "myresourcegroup"
$kuduCreds = getKuduCreds $appName $resourceGroup
$code =  getFunctionKey $appName $functionName $kuduCreds
$funcUri = "https://$appName.azurewebsites.net/api/$functionName?code=$code"

# call the function
Invoke-RestMethod -Method POST -Uri $funcUri

Obviously that's just showing how to retrieve the keys for a function, but once you know how to authorize a call to this API, calling the other methods is pretty straightforward.

Hope you found this helpful. It's certainly been very useful for me in automating tests for my function apps.

Want to learn more about how easy it is to get up and running with Azure Functions? Be sure to check out my Pluralsight course Azure Functions Fundamentals.

0 Comments Posted in:

I am a huge fan of Azure Functions but one of the challenges people who are new to it face is the sheer number of choices it gives you. For almost every task, there are multiple ways of accomplishing it. This means that people are either confused about which option to take, or unaware that there are alternatives to the first method they discovered.

In this post I'll go through some of the choices at your disposal, and give some suggestions to help you decide which is the most appropriate for your function apps.

Three environments to write functions in

Most people's first introduction to Functions is a demo showing how you can write code directly in the Azure portal! This is great for quick demos and experiments. But it's not what you should be using in production.

You can also create functions in Visual Studio. Visual Studio has its own special Azure Functions tooling, making it easy to create new Azure Function App projects and providing templates for new functions and local testing and debugging.

But you don't need to use Visual Studio. You can also develop functions with any text editor and the Azure Functions command line tools. The Azure Functions command line tooling also lets you easily create new function apps, functions and do local testing.

Which should I use? My recommendation: use the portal only for demos or very quick experimental stuff. For real apps, pick Visual Studio if that is your regular development tool, and otherwise use a good text editor (e.g. VS Code) in conjunction with the Azure Functions command line tooling.

Multiple languages to write functions with

Azure Functions currently fully supports three languages - C#, JavaScript and F#. There are also more languages in development at varying stages of completion. Java and Python are likely to be the next two to be supported. You can request support for other languages on the Azure Functions user voice feedback site.

Which should I use? Obviously use your favourite language, although my recommendation is to stick to the fully supported languages if at all possible. They have the best documentation, stability and binding support.

You are of course completely free to mix and match languages within a single function app. I show how to do this in my Functions Todo Backend sample.

Two ways to write C# functions

Not only can you write functions in multiple languages, but if you choose C# there are two separate ways of doing it. First you can create .csx files (C# script). This is what you use if you code in the portal and was the original C# programming model of Azure Functions. It's still supported but now there is also the ability to create "pre-compiled functions", where you write regular C# code which is compiled into a DLL. This has benefits for performance and testability.

Which should I use? Unless you're doing a quick experiment in the portal, the precompiled functions approach is the one I recommend. This is what the Visual Studio tooling will create for you, but it seems that the current version of the Azure Functions tooling still uses the csx approach (I haven't checked whether the new .NET Core version of the tooling does this too, which brings us to the next choice...)

Two versions of the Azure Functions runtime

Even more confusingly, there are two versions of the Azure Functions runtime. There's "Version 1" which is still the current GA version of Azure Functions (at the time of writing), and runs on the full .NET framework, making it Windows only. That's absolutely fine as Azure Functions is serverless so you don't really need to care what the underlying OS is.

However, a new version 2 of the Azure Functions runtime is in development and is built on .NET Core. This makes it cross-platform, which opens up local testing on non-Windows platforms as well as the ability to host the runtime in Docker containers and more. It's the future of Azure Functions and has binding and language extensibility built in which makes it a much better platform for future innovation.

Which should I use? For the moment, stick to version 1 unless you absolutely need cross platform. But once V2 goes GA, I'd recommend all new development uses that.

Two ways to get billed

Most people know that Azure Functions offers a serverless pricing model. You just pay for the time that your functions are running. If they don't run at all, you pay nothing. This is a hugely attractive pricing model and can result in dramatic cost savings. This model is called the "consumption" plan - you're only paying for what you consume.

However, there is an alternative pricing model in which you pay for an app service plan. This is the same pricing model as Azure App Service. You pay a fixed monthly price which will reserve you your own VM (or multiple VMs) dedicated to your function app.

Which should I use?. In most scenarios the consumption plan makes the most sense, but the App Service plan offers a few advantages in certain situations. First, it doesn't restrict the duration your functions can run for, which is important if you have functions that last for more than 5 minutes (although that may be a sign your function is doing too much). It also provides predictable pricing model - there's no risk of accidentally running up a huge bill because of heavy incoming load.

Multiple ways to trigger your functions

Some people seem to be under the impression that all Azure Functions are triggered by HTTP requests. This is not the case. Azure Functions supports multiple "triggers". A HTTP request is just one kind of trigger. Others include messages on queues, or timers, or blobs appearing in a storage container.

Event Grid events can also trigger functions. This is a new addition to Azure, and not all services fully support it yet, but there is a lot of momentum behind it and soon it will mean that pretty much anything that happens in any of your Azure resources can trigger a function execution.

Which should I use? Use whichever trigger fits your needs. HTTP requests are good for building APIs or handling webhooks, but in many cases you don't need HTTP request triggers at all.

Numerous ways to deploy

OK, now we're getting into crazy territory. There are literally so many ways to deploy your Azure Functions it makes your head spin. And still some people aren't happy with the options we've got now!

A big part of the reason there are so many options is that Azure Functions is based on App Service and that already had a whole bunch of ways to deploy. Let's go through the options...

  1. Publish manually from Visual Studio. Visual Studio has built-in tooling that lets you easily deploy your Function App either to an existing Function App or to a brand new one, all within the IDE. Under the hood it uses webdeploy (I think).
  2. You can publish with webdeploy, just like you can a regular web app. There's an msbuild target you can use to create the deployment package and then you can call the tool, but this option is a bit cumbersome and there are easier options.
  3. You can simply FTP your function code onto the app service plan's disk.
  4. You can use the Kudu REST API to upload the code / binaries for your function. This API lets you individually add and remove individual files on the host.
  5. You can use the Kudu "zipdeploy" API to upload a zipped package of your code
  6. You can set up continuous deployment watching a Git repository so that every time you push to that repo, Kudu will clone it and build it. (except when it doesn't get push notifications, in which case you have to trigger it manually)
  7. There is a variation on the Git option where it is a "local" repository - that is, rather than pushing to a repo hosted externally on GitHub or VSTS, you push to a repo stored on your Function App own storage.
  8. As well as using Git you can sync from other sources including Dropbox, OneDrive, or Mercurial repositories on BitBucket.
  9. There's a brand new "run from zip" option where you provide a URL to a zip containing your code (e.g. with a SAS token in a blob storage account) and functions. This offers some performance benefits over the previous techniques, and so could end up becoming the recommended approach in the future. It's still in an experimental state at the moment though.
  10. There's a variation on the new "run from zip" technique where you put the zip into a special SitePackages folder and update a text file to point to it. This avoids the need for long-lived SAS tokens and also provides rollback capabilities and may be a preferred option for some people.

I told you there were a lot of options! And that doesn't even count logging into the Kudu console and dragging and dropping files in, or coding directly in the Azure portal!

Which one should I use? It's not an easy decision. Here's my recommendations. Only use right-click publish from VS if you're just testing and experimenting. Use Git integration for the sort of small projects where having your own full-blown CI build pipeline would be overkill - you just want to commit changes, push to GitHub/VSTS and let it go live in due course (I'm actually using the Git deployment technique for this blog). Use the Kudu zip deploy API for a more enterprise CI/CD pipeline where your build creates the assets and performs some tests before pushing them live. And keep an eye on the "run from zip" technique - I suspect that will become the recommended approach once some of the issues have been ironed out.

Two ways to test and debug

The great thing about the Azure Functions tooling is it lets you test locally. This provides a great rapid development process saving you pushing to the cloud or the complexities of debugging remotely. Most of the time you will use the Azure Storage Emulator in conjunction with local testing if you're working with blobs, queues or tables, but you can of course point to a real Azure storage account while you're testing locally.

And it's possible to turn on remote debugging and connect your Visual Studio directly to the cloud. The last time I tried this it was quite an unreliable process, but hopefully things have improved a bit in the meantime.

Which one should I use? Hopefully, local testing and debugging is good enough 99% of the time, but its nice to know you can attach the debugger to Azure for those cases where an issue is only showing up in production. And if you have a good CI/CD process set up, you can easily deploy a test instance of your function app to run integration or performance tests against.

Three ways to host the runtime

We've already mentioned the obvious two places you'll host the runtime - either in the cloud on an App Service, or locally for testing and debugging. But you can also host the Azure runtime in a container, by using the microsoft/azure-functions-runtime Docker image. This is using the .NET Core version 2 of the runtime so it can run on Linux containers.

Which one should I use? Normally, you'd simply let App Service host the runtime for you, but the containerization option opens up lots of possibilities to use your Azure Functions in on premises environments, or in other clouds.

Two ways to monitor your functions

Out of the box, Azure Functions is associated with an Azure Storage account, and it uses table storage in that account to record details of the invocation of each function, including its logs and timing. Some of that information is surfaced to you in the Azure portal, so for each function you can see the recent invocations and dive into individual instances to see the log output.

It is however, quite a rudimentary experience, and that's where App Insights integration comes in. It is very straightforward to configure your Azure Functions to send data to App Insights, and if you do so, you'll benefit from much richer querying and analytics.

Which one should I use? This one is easy, enable App Insights for all your Function Apps.

Three ways to secure your HTTP functions

Let's end with one which I don't think has quite enough choice yet. For the most part, Azure Functions are secured by virtue of the fact that only an authorized caller can trigger them. For example, if your function is triggered by a queue message, then only someone who can post to that queue can trigger your function.

But for HTTP triggered functions, they have public endpoints accessible from the internet, and so you need to think carefully about security. By default, Azure Functions provides a system of authorization keys. You have to pass the key as a query string parameter or header to be able to call the function. In server to server instances this may be adequate, but is not feasible as a security mechanism for client side apps, as you wouldn't want to expose the secret key.

Currently your options for APIs intended to be called from the browser are limited. First of all, you have the browser's CORS protection and Azure Functions lets you configure CORS settings for your Function App. And there is an App Service feature called "App Service Authentication" which turns on authentication globally for every single web request coming into that app. It supports a bunch of common identity providers like facebook and google, as well as Active Directory integration.

But I'd like to see it much easier for us to configure bearer token authentication on a per-function basis, allowing a mix of anonymous and authenticated functions. If Azure Functions could do this automatically, as well as provide easy integration with Managed Service Identities, that would be awesome.

What should I use? Your choice of security mechanism depends on whether you are willing to trust your callers with function keys or not. You could of course implement your own code to examine and validate a bearer token, but that's something I'd rather see the platform take care of that, as it's all too easy to make mistakes rolling your own security implementations.


As you can see, the Azure Functions platform is very rich and offers a wide variety of choices. These can seem overwhelming at first, but hopefully this guide gives you a starting point to decide which features of the Azure Functions platform are right for your application.

Want to learn more about how easy it is to get up and running with Azure Functions? Be sure to check out my Pluralsight course Azure Functions Fundamentals.