public static async Task Run(
            [QueueTrigger("%LoadQueueName%", Connection = "AzureWebJobsStorage")] LoadJob job,
            ILogger log)
        {
            var blobClient = blobClients.GetOrAdd(job.Account, (accName) =>
            {
                string connectionEnvironmentVariableName = $"STORAGECONNECTION_{job.Account}";
                string connectionString = Environment.GetEnvironmentVariable(connectionEnvironmentVariableName)
                                          ?? throw new Exception($"Cannot find connection string environment variable '{connectionEnvironmentVariableName}'.");

                CloudStorageAccount account = CloudStorageAccount.Parse(connectionString);
                return(account.CreateCloudBlobClient());
            });

            var container = blobClient.GetContainerReference(job.Container);

            var inputBlock = new BufferBlock <ThermostatLog>();

            var sendBlock = new ActionBlock <ThermostatLog>(async thermostatLog =>
            {
                var filename = $"{thermostatLog.GetFileIdentifier()}.csv";

                var blob = container.GetBlockBlobReference(filename);
                blob.Properties.ContentType = "text/csv";

                using (var stream = await blob.OpenWriteAsync())
                    using (var writer = new StreamWriter(stream))
                    {
                        csvUtils.ToCsv(writer, thermostatLog.Readings);
                    }
            }, new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = 16
            });

            inputBlock.LinkTo(sendBlock, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            var random = new Random();

            for (int i = 0; i < job.Size; i++)
            {
                inputBlock.Post(ThermostatLog.GenerateRandomLog(random));
            }

            inputBlock.Complete();
            await sendBlock.Completion;
        }
        public static async Task Run(
            [TimerTrigger("*/10 * * * * *")] TimerInfo myTimer,
            [Queue("%LoadQueueName%", Connection = "AzureWebJobsStorage")] IAsyncCollector <LoadJob> loadJobs,
            ILogger log)
        {
            var batchCount    = int.Parse(Environment.GetEnvironmentVariable("BatchCount") ?? "10");
            var batchSize     = int.Parse(Environment.GetEnvironmentVariable("BatchSize") ?? "10");
            var containerName = Environment.GetEnvironmentVariable("ContainerName") ?? "container01";
            var accountName   = Environment.GetEnvironmentVariable("AccountName") ?? "pbatumfuncblobwus2acc01";

            var loadJob = new LoadJob
            {
                Account   = accountName,
                Container = containerName,
                Size      = batchSize
            };

            var bufferBlock     = new BufferBlock <LoadJob>();
            var addMessageBlock = new ActionBlock <LoadJob>(async job =>
            {
                await loadJobs.AddAsync(job);
            }, new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = 32
            });

            bufferBlock.LinkTo(addMessageBlock,
                               new DataflowLinkOptions {
                PropagateCompletion = true
            });

            for (int i = 0; i < batchCount; i++)
            {
                bufferBlock.Post(loadJob);
            }

            bufferBlock.Complete();
            await addMessageBlock.Completion;
        }