<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Technozure</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/amitagarwal/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/amitagarwal/feed.xml</link>
    <description />
    <lastBuildDate>Thu, 05 Apr 2018 06:19:44 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Azure Function Apps: Performance Considerations</title>
      <link>https://docs.microsoft.com/archive/blogs/amitagarwal/azure-function-apps-performance-considerations</link>
      <pubDate>Tue, 03 Apr 2018 21:50:09 GMT</pubDate>
      <dc:creator><![CDATA[Amit Agarwal (amagar)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/amitagarwal/?p=935</guid>
      <description><![CDATA[While working with Azure Function Apps we often come across performance issues where we see the rate...]]></description>
      <content:encoded><![CDATA[While working with Azure Function Apps we often come across performance issues where we see the rate of message processing or the rate at which API calls are being served is not even near to the expected one.

Before we start digging into these issues I would like to mention that no service/product is perfect. As and when product grows it needs more inputs for improvement. It is possible that even after following the best practices the applications may face issues but then Microsoft is always open for feedback and that’s how we grow and keep improving.

This blog assumes the basic knowledge about the Azure Function App.

Let’s discuss the commonly faced Performance Issues one by one.

When we talk about performance it’s commonly about, but not limited to,
<ul>
 	<li>High CPU Consumption</li>
 	<li>High Memory Consumption</li>
 	<li>Port/ Outbound Socket Consumption</li>
 	<li>No. of threads being spawned up</li>
 	<li>No of pending requests in the HTTP Pipeline</li>
</ul>
While creating a Function App one should <strong>keep in mind</strong> the fact that moving from Consumption Plan to App Service Plan and vice-versa is not possible once the function is created. However, if you delete the Function app and recreate it on the other type of hosting plan then that is possible for obvious reasons.

Consumption plan takes care of scaling out whenever there is a need. To describe in simple terms scaling happens when the current processing /output &lt;= the current input. Scaling (scale out) happens when this equation doesn’t hold true. All these performance issues usually we face on Consumption plan where we don’t have the control over scaling up or scaling out the hosting plan. In addition to this, the VM specs are pretty much limited to the consumption plan. <strong><span>Up to 1.5 GB Ram and 1 core CPU</span></strong> is what we get in one instance where the Function app is running, which is not too great I would say. The other limits are:

<a href="https://msdnshared.blob.core.windows.net/media/2018/04/clip_image001.png"><img width="801" height="446" title="clip_image001" style="border: 0px currentcolor" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2018/04/clip_image001_thumb.png" border="0" /></a>

We should design and develop our function app in a way avoiding performing an intensive tasks taking high CPU, High Memory, spawning large no of threads, opening large no of outbound socket connections etc.

Once the application usage gets past to these limits the processing rate of messages gets reduced and then the scale controller adds a new instance of a machine and the load gets distributed to keep up the processing rate.

However, it takes at <span><strong>least 10 seconds</strong></span> to add a new instance and then the load balancing of the events starts.

Especially with HTTP triggers, it takes a bit longer to add more instances. So if we are running load tests we may see a little bit higher time taken by the requests to complete as they all start to go on a single instance and we can observe the HTTP pipeline growing up initially. However when the new instances are added then processing speeds up and within <strong><span>20-30 Min of time</span></strong>, the high load(10K requests) will be settled.

This was about the Consumption plan.

In case we use the app service plan then definitely we are choosing the VM specs we want our application to run on. So with features like auto-scaling, we can have the control on when to trigger scaling and also what size of VM to choose. Also for plans on Standard and above there is an option to use Traffic Manager as well to distribute the load.

This was about the VM and how to manage or effectively utilize the VM resources.

While building the application one should also consider the connections to other services internal or external to Azure which the Function app is going to connect while processing. The limit for no of outbound socket connections alive at any given point in time is 300 on Consumption plan. It seems to be pretty low. However, scale-out happens (indirectly) when this limit is reached.

Let's see how this works.

Suppose there is a Function app (Consumption Plan) running on one instance and the Function app itself is making 400 connections to any other service like SQL, COSMOS DB. For one user request to the Function App, there are 400 connections being made to the external service. In this case, the auto scale-out which happens on consumption plan will not help as all those outgoing connections are coming from same worker process and same instance of the worker process. Now imagine after the scale out happens, each instance will have its own worker process and each worker process will make 400 calls to the external service and every worker process in every instance will start failing with the same issue.

The consumption plan scaling will work in a scenario where there are 400 requests to the Function app itself and every function call making one connection to external service. So if initially we have one instance to start with it will get 400 calls then as it will not be able to process more than 300 calls (it will make 300 connections to the external service and will consume all 300 ports) the consumption plan scaling will happen and will add a new instance to serve rest of the calls and balance out the further load.

Along with these considerations, we can implement concurrent/parallel processing of messages by using respective trigger properties in HOST.JSON file of the Function app. These are:
<pre style="font-family: Consolas;font-size: 13;color: black;background: white">{
 
  <span style="color: #2e75b6">"eventHub"</span>: {
    <span style="color: #2e75b6">"maxBatchSize"</span>: 64,
    <span style="color: #2e75b6">"prefetchCount"</span>: 256,
    <span style="color: #2e75b6">"batchCheckpointFrequency"</span>: 1
  },
 
  <span style="color: #2e75b6">"http"</span>: {
    <span style="color: #2e75b6">"routePrefix"</span>: <span style="color: #a31515">"api"</span>,
    <span style="color: #2e75b6">"maxOutstandingRequests"</span>: 20,
    <span style="color: #2e75b6">"maxConcurrentRequests"</span>: 10,
    <span style="color: #2e75b6">"dynamicThrottlesEnabled"</span>: <span style="color: blue">false</span>
  },
 
  <span style="color: #2e75b6">"queues"</span>: {
    <span style="color: #2e75b6">"maxPollingInterval"</span>: 2000,
    <span style="color: #2e75b6">"visibilityTimeout"</span>: <span style="color: #a31515">"00:00:30"</span>,
    <span style="color: #2e75b6">"batchSize"</span>: 16,
    <span style="color: #2e75b6">"maxDequeueCount"</span>: 5,
    <span style="color: #2e75b6">"newBatchThreshold"</span>: 8
  },
  <span style="color: #2e75b6">"serviceBus"</span>: {
    <span style="color: #2e75b6">"maxConcurrentCalls"</span>: 16,
    <span style="color: #2e75b6">"prefetchCount"</span>: 100,
    <span style="color: #2e75b6">"autoRenewTimeout"</span>: <span style="color: #a31515">"00:05:00"</span>
  }
}</pre>
While connecting to the external services it’s always advisable to use <strong>connection pooling</strong>. However, that also depends on what scenario you are working on.

So the considerations discussed above, the concurrent processing properties and connection pooling combined together can significantly improve the function app performance.

Before ending the blog couple of important points I want to share here which are worth keeping in mind when we are comparing the performance of Function app on Consumption plan vs on App Service plan Vs the same code in a Web App on a VM
<ol>
 	<li>Compute power of all the three kinds of VM’s are different.</li>
 	<li>If we are running the same code on the Function app, app service plan and in an application on VM with the similar configuration like RAM and CPU, there will be a difference in computing power observed as the underlying VM’s can be of different series. Web apps use A Series VM which are for moderate loads. When we are choosing the actual VM, we can take it of any series we want and usually we end up in choosing D series VM having high computing power. <a href="https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs#a-series">Here</a> is an article to go through all the series of VM’s available on Azure.</li>
</ol>
I hope this will give you all a little more insight on how to deal with Azure Function Apps Performance.]]></content:encoded>
    </item>
    <item>
      <title>Azure Function Apps: Organizing the Azure Function Apps under same Consumption Plan</title>
      <link>https://docs.microsoft.com/archive/blogs/amitagarwal/azure-function-apps-organizing-the-azure-function-apps-under-same-consumption-plan</link>
      <pubDate>Sun, 14 Jan 2018 16:08:02 GMT</pubDate>
      <dc:creator><![CDATA[Amit Agarwal (amagar)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/amitagarwal/?p=765</guid>
      <description><![CDATA[When we create an Azure Function App from Azure Portal on a Consumption plan we don't have the...]]></description>
      <content:encoded><![CDATA[When we create an Azure Function App from Azure Portal on a Consumption plan we don't have the control over which Consumption plan to use.
In other words, if we want to put all of the azure functions under the same Consumption plan it doesn't seem to be possible.

However, it is possible but only at the time when creating the Azure Function App.

There are two ways (at least what I am aware of) of doing this.
1. Using the ARM template deployment
2. Using the Visual Studio.

<strong>Function App Deployment Using ARM template</strong>

Here is the link to the template for Azure Function App deployment on Consumption plan.
<a href="https://github.com/Azure/azure-quickstart-templates/tree/master/101-function-app-create-dynamic">https://github.com/Azure/azure-quickstart-templates/tree/master/101-function-app-create-dynamic</a>

While defining the resources to create/deploy we can mention existing Consumption plan name/id value for "serverFarmId".
"resources":
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: #a31515">"resources"</span>:
[
  {
    <span style="color: #2e75b6">"apiVersion"</span>: <span style="color: #a31515">"2015-08-01"</span>,
    <span style="color: #2e75b6">"type"</span>: <span style="color: #a31515">"Microsoft.Web/sites"</span>,
    <span style="color: #2e75b6">"name"</span>: <span style="color: #a31515">"[variables('functionAppName')]"</span>,
    <span style="color: #2e75b6">"location"</span>: <span style="color: #a31515">"[resourceGroup().location]"</span>,
    <span style="color: #2e75b6">"kind"</span>: <span style="color: #a31515">"functionapp"</span>,
    <span style="color: #2e75b6">"properties"</span>: {
      <span style="color: #2e75b6">"serverFarmId"</span>: <span style="color: #a31515">"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"</span>
    }
  }
]</pre>
We can also create just the consumption plan without the Function App running on it and again by using the ARM template.
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: #a31515">"resources"</span>: [
  {
    <span style="color: #2e75b6">"type"</span>: <span style="color: #a31515">"Microsoft.Web/serverfarms"</span>,
    <span style="color: #2e75b6">"apiVersion"</span>: <span style="color: #a31515">"2015-04-01"</span>,
    <span style="color: #2e75b6">"name"</span>: <span style="color: #a31515">"[variables('hostingPlanName')]"</span>,
    <span style="color: #2e75b6">"location"</span>: <span style="color: #a31515">"[resourceGroup().location]"</span>,
    <span style="color: #2e75b6">"properties"</span>: {
      <span style="color: #2e75b6">"name"</span>: <span style="color: #a31515">"[variables('hostingPlanName')]"</span>,
      <span style="color: #2e75b6">"computeMode"</span>: <span style="color: #a31515">"Dynamic"</span>,
      <span style="color: #2e75b6">"sku"</span>: <span style="color: #a31515">"Dynamic"</span>
    }
  }
]</pre>
This means the creation of Consumption plan and the Azure Function app can be decoupled and not necessarily be clubbed together. However while creation of a Function app we need to make sure the Consumption plan exists and there is a dependency mentioned on the Function App for the Consumption plan.

<strong>Using Visual Studio</strong>

After creating the Azure Function App in Visual Studio 2017 when we click on publish, a dialogue pops up asking for the Publish target as shown below.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/14.jpg"><img width="808" height="542" title="1" style="border: 0px currentcolor" alt="1" src="https://msdnshared.blob.core.windows.net/media/2018/01/1_thumb3.jpg" border="0" /></a>

If we chose <strong>Azure Function App &gt;&gt; Create New</strong> we will further get the option to write the <strong>App Name, Chose the Subscription, Resource Group, and the App Service Plan</strong>.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/25.jpg"><img width="811" height="612" title="2" style="border: 0px currentcolor" alt="2" src="https://msdnshared.blob.core.windows.net/media/2018/01/2_thumb3.jpg" border="0" /></a>

If we expand the App Service Plan drop-down list we will get to see all the plans listed out to chose.

For Eg. :

<strong>myplan1 (S1, South Central US)</strong>
<strong>myplan2 (B1, East US)</strong>
<strong>myplan3 (D1, East US)</strong>
<strong>myconsumptionplan1 (Y1, Central Canada)</strong>

These are just the examples but if we have any plan for the subscription it will list out the similar way.

First three plans are quite clear as they belong to Standard(S1), Basic(B1), Shared(D1) pricing tiers respectively.
The last app service plan <strong>"myconsumptionplan1 (Y1, Central Canada)"</strong> is a Consumption plan and it is denoted by letter <strong>"Y"</strong>.

So an existing Consumption plan can be chosen from this option. Also, there is a button <strong>"new"</strong> in front of the App Service Plan field on this screen from where we can create a Consumption plan and then can use it.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/33.jpg"><img width="819" height="620" title="3" style="border: 0px currentcolor" alt="3" src="https://msdnshared.blob.core.windows.net/media/2018/01/3_thumb2.jpg" border="0" /></a>

This way we can organize our Azure Function Apps to run on a particular Consumption plan which can make the tracking easier]]></content:encoded>
    </item>
    <item>
      <title>Azure Function Apps: Trigger in Azure SQL /SQL Server to execute Azure Function</title>
      <link>https://docs.microsoft.com/archive/blogs/amitagarwal/azure-function-apps-trigger-in-azure-sql-sql-server-to-execute-azure-function</link>
      <pubDate>Thu, 11 Jan 2018 02:01:44 GMT</pubDate>
      <dc:creator><![CDATA[Amit Agarwal (amagar)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/amitagarwal/?p=705</guid>
      <description><![CDATA[Ever thought of SQL (on VM or On-Premise server) Input Trigger for the Function app?

There is no...]]></description>
      <content:encoded><![CDATA[Ever thought of SQL (on VM or On-Premise server) Input Trigger for the Function app?

There is no predefined input trigger for SQL in Azure functions. Which means there is no way to trigger an Azure function on any change in the SQL data. Triggers mainly at present are Blob, Queue, Table, Eventhub, Http, Timer etc.

In order to make an azure function trigger on a SQL change, there can be two possible ways.

1. Defining Custom Binding in Azure functions

2. If not the binding on Azure Functions side, then it can be a SQL trigger invoking an Azure Functions HTTP trigger.

The first option is quite tricky and may need a proper understanding of how Azure functions existing bindings are defined and how they work. The second option is not a solution rather it's a workaround but easy to implement.

In order to make an HTTP call from SQL, we need to make use of the concept of CLR assemblies in SQL Server.

So how it works is we create an assembly having methods to make HTTP calls in Visual Studio and register this assembly in SQL Server. Once this assembly is registered we can use the method inside the assembly to make a call to function app HTTP trigger.

Let's take a closer look step by step.

In the below code I have created two methods "POST" and "GET" to make HTTP calls.
<pre style="font-family: Consolas;font-size: 13;color: black;background: white">[Microsoft.SqlServer.Server.<span style="color: #2b91af">SqlFunction</span>(DataAccess = <span style="color: #2b91af">DataAccessKind</span>.Read)]
<span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">SqlString</span> HttpGetFromSQL(<span style="color: #2b91af">SqlString</span> uri)
{
    <span style="color: #2b91af">SqlString</span> document = <span style="color: #2b91af">SqlString</span>.Null;
    <span style="color: #2b91af">WebRequest</span> req = <span style="color: #2b91af">WebRequest</span>.Create(<span style="color: #2b91af">Convert</span>.ToString(uri));
    <span style="color: blue">try</span>
    {
        <span style="color: blue">using</span> (<span style="color: #2b91af">WebResponse</span> resp = req.GetResponse())
        {
            <span style="color: blue">using</span> (<span style="color: #2b91af">Stream</span> dataStream = resp.GetResponseStream())
            {
                <span style="color: blue">using</span> (<span style="color: #2b91af">StreamReader</span> rdr = <span style="color: blue">new</span> <span style="color: #2b91af">StreamReader</span>(dataStream))
                {
                    document = (<span style="color: #2b91af">SqlString</span>)rdr.ReadToEnd();
                }
            }
        }
    }
    <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
    { }        
    <span style="color: blue">return</span> (document);
}</pre>
<pre style="font-family: Consolas;font-size: 13;color: black;background: white">[Microsoft.SqlServer.Server.<span style="color: #2b91af">SqlFunction</span>(DataAccess = <span style="color: #2b91af">DataAccessKind</span>.Read)]
<span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">SqlString</span> HttpPostFromSQL(<span style="color: #2b91af">SqlString</span> uri, <span style="color: #2b91af">SqlString</span> postData)
{
    <span style="color: #2b91af">SqlString</span> document=<span style="color: #2b91af">SqlString</span>.Null;
    <span style="color: blue">try</span>
    {
        <span style="color: blue">byte</span>[] postByteArray = <span style="color: #2b91af">Encoding</span>.UTF8.GetBytes(<span style="color: #2b91af">Convert</span>.ToString(postData));
        <span style="color: #2b91af">WebRequest</span> req = <span style="color: #2b91af">WebRequest</span>.Create(<span style="color: #2b91af">Convert</span>.ToString(uri));
        req.Method = <span style="color: #a31515">"POST"</span>;
        req.ContentType = <span style="color: #a31515">"application/x-www-form-urlencoded"</span>;
        <span style="color: blue">using</span> (<span style="color: #2b91af">Stream</span> dataStream = req.GetRequestStream())
        {
            dataStream.Write(postByteArray, 0, postByteArray.Length);
        }
 
        <span style="color: blue">using</span> (<span style="color: #2b91af">WebResponse</span> resp = req.GetResponse())
        {
            <span style="color: #2b91af">Stream</span> dataStream = resp.GetResponseStream();
            <span style="color: blue">using</span> (<span style="color: #2b91af">StreamReader</span> rdr = <span style="color: blue">new</span> <span style="color: #2b91af">StreamReader</span>(dataStream))
            {
                document = (<span style="color: #2b91af">SqlString</span>)rdr.ReadToEnd();
            }
        }
    }
    <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ex)
    { }
    <span style="color: blue">return</span> (document);
}</pre>
<strong>NOTE: For the integration of this code with SQL Server we need "Microsoft.SqlServer.Server" assembly.</strong>

Once we have the assembly ready we can enable the SQL Server to run the CLR code.
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: blue">EXEC</span> <span style="color: maroon">sp_configure</span><span style="color: blue"> </span><span style="color: red">'clr enabled'</span><span style="color: gray">;</span>
<span style="color: blue">EXEC</span> <span style="color: maroon">sp_configure</span><span style="color: blue"> </span><span style="color: red">'clr enabled'</span><span style="color: gray">,</span> 1<span style="color: gray">;</span>
<span style="color: blue">RECONFIGURE</span><span style="color: gray">;</span></pre>
In order to enable the SQL Server to access the resources outside of the SQL Server, we need to mark the database as TRUSTWORTHY ON. This is needed to run the assembly which we will register to have the "EXTERNAL ACCESS".
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: blue">ALTER</span> <span style="color: blue">DATABASE</span> TestDB <span style="color: blue">SET</span> <span style="color: blue">TRUSTWORTHY</span> <span style="color: blue">ON</span><span style="color: gray">;</span>
</pre>
Now let's register the assembly with the SQL Server.
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: blue">USE</span> TestDB
<span style="color: blue">GO</span>
 
<span style="color: blue">CREATE</span> <span style="color: blue">ASSEMBLY</span> FunctionAppReq
<span style="color: blue">FROM</span> <span style="color: red">'C:\Amit Data\FunctionAppClassLibrary.dll'</span>
<span style="color: blue">WITH</span> <span style="color: blue">PERMISSION_SET</span><span style="color: gray">=</span><span style="color: blue">EXTERNAL_ACCESS</span><span style="color: gray">;</span>
 
<span style="color: blue">GO</span></pre>
Once the Assembly is registered you can call the specific functions of the assembly in a SQL Function.
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: blue">CREATE</span> <span style="color: blue">FUNCTION</span> dbo<span style="color: gray">.</span>get_web_request<span style="color: gray">(</span>
     @uri        <span style="color: blue">nvarchar</span><span style="color: gray">(</span><span style="color: magenta">max</span><span style="color: gray">)</span>
<span style="color: gray">)</span>
<span style="color: blue">RETURNS</span> <span style="color: blue">nvarchar</span><span style="color: gray">(</span><span style="color: magenta">max</span><span style="color: gray">)</span>
<span style="color: blue">AS</span>
<span style="color: blue">EXTERNAL</span> <span style="color: blue">NAME</span> FunctionAppReq<span style="color: gray">.</span>Functions<span style="color: gray">.</span>HttpGetFromSQL<span style="color: gray">;</span>
 
<span style="color: blue">GO</span></pre>
Once this function is ready we can now create any trigger on any table to call this function and in turn call the HTTP trigger of the azure functions.
<pre style="font-family: Consolas;font-size: 13;color: black;background: white"><span style="color: blue">CREATE</span> <span style="color: blue">TRIGGER</span> StudentsAfterInsertTrigger <span style="color: blue">ON</span> TestDb<span style="color: gray">.</span>dbo<span style="color: gray">.</span>Students
<span style="color: blue">AFTER</span> <span style="color: blue">INSERT</span>  
<span style="color: blue">AS</span>  
<span style="color: blue">begin</span>
 
 <span style="color: blue">declare</span> @str <span style="color: blue">varchar</span><span style="color: gray">(</span><span style="color: magenta">max</span><span style="color: gray">);</span>
 <span style="color: blue">set</span> @str <span style="color: gray">=</span> dbo<span style="color: gray">.</span>get_web_request<span style="color: gray">(</span><span style="color: red">'http:\\functionapptest.azurewebsites.net\api\httptriggerfunction?param1=val1$param2=val2'</span><span style="color: gray">);</span>
 
<span style="color: blue">end</span></pre>]]></content:encoded>
    </item>
    <item>
      <title>Azure Web Jobs: Custom Schedule for Azure Web Job Timer Triggers</title>
      <link>https://docs.microsoft.com/archive/blogs/amitagarwal/custom-schedule-for-azure-web-job-timer-triggers</link>
      <pubDate>Mon, 01 Jan 2018 15:43:54 GMT</pubDate>
      <dc:creator><![CDATA[Amit Agarwal (amagar)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/amitagarwal/?p=535</guid>
      <description><![CDATA[CRON Expression is a nice way to define the schedule for the Timer Tigger in Azure Web jobs/Function...]]></description>
      <content:encoded><![CDATA[CRON Expression is a nice way to define the schedule for the Timer Tigger in Azure Web jobs/Function apps. Though, sometimes it can be a little tricky.

Understanding and defining the CRON expression can be very tricky for some schedules and actual interpretation may not be the same what you had configured in the CRON expression. Though the positive side of defining the CRON expression for timer triggers is that, whenever a change is needed it’s quick and can be done via the KUDU site.

Azure Web Job SDK has the classes <strong>“DailySchedule” &amp; “WeeklySchedule”</strong> (Nuget <strong>Microsoft.Azure.WebJobs.Extensions</strong>) which can be an alternative to the CRON expressions, which can make the schedule definition easy to read and define.

Using these classes, we can configure very tricky and complex schedules as below:

•    Every day but at different timings with no regular interval, let say every day 11:00 AM, 01:00 PM, 04:30 PM &amp; 09:15 PM (Quite tricky)

•    On Tuesday 11:00 AM, on Thursday 12:00 PM and on Saturday 06:00 AM(Complex)

Frankly, I didn't even try creating CRON expression for above scenarios :), as being developer, it was quite easy for me to use these classes and configure above schedule in the configuration file.

Lets talk about the classes “<b>DailySchedule</b>” &amp; “<b>WeeklySchedule</b>” now.

<b>“</b><b><u>DailySchedule</u>”</b>

This class is an inbuilt class for timers under the namespace <strong>“Microsoft.Azure.WebJobs.Extensions.Timers”</strong> and is inherited from “<b>TimerSchedule</b>” which is the base class for Timer Triggers.

Using the constructor of class “<b>DailySchedule</b>” we can define the daily schedule. The constructor takes in the collection of <b>System.TimeSpan strings</b> or collection of <b>System.TimeSpan instances</b>.

“<b><u>WeeklySchedule</u></b><b>”</b>

Just like the “<b>DailySchedule</b>” class this class is also under the namespace <strong>“Microsoft.Azure.WebJobs.Extensions.Timers”</strong> and is inherited from the “<b>TimerSchedule</b>” class. Using the <b>Add</b> method defined in this class we can define the weekly schedule. Add method takes “<b>DayOfWeek</b>” and “<b>TimeSpan”</b> as the two arguments to define the schedule.

In order to make use of these classes we need to create our own classes, inherit these classes and use the methods to define the schedule. Once the custom class is defined we need to define the TimerTriggerAttribute as a <strong>typeof</strong> the custom class.

Lets take a look at the examples of Usage of these classes and make it more clear.

Example 1. <b>DailySchedule.</b>
<pre style="font-family:Consolas;font-size:13;color:black;background:white"><span style="color:green">//&nbsp;This&nbsp;function&nbsp;will&nbsp;get&nbsp;triggered/executed&nbsp;on&nbsp;a&nbsp;custom&nbsp;schedule&nbsp;on&nbsp;daily&nbsp;basis.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;<span style="color:blue">static</span>&nbsp;<span style="color:blue">void</span>&nbsp;CustomTimerJobFunctionDaily([<span style="color:#2b91af">TimerTrigger</span>(<span style="color:blue">typeof</span>(<span style="color:#2b91af">CustomScheduleDaily</span>))]&nbsp;<span style="color:#2b91af">TimerInfo</span>&nbsp;timerInfo)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">&quot;CustomTimerJobFunctionDaily&nbsp;ran&nbsp;at&nbsp;:&nbsp;&quot;</span>&nbsp;+&nbsp;<span style="color:#2b91af">DateTime</span>.UtcNow);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//Class&nbsp;for&nbsp;custom&nbsp;schedule&nbsp;daily.</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">CustomScheduleDaily</span>&nbsp;:&nbsp;<span style="color:#2b91af">DailySchedule</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;CustomScheduleDaily()&nbsp;:&nbsp;<span style="color:blue">base</span>(<span style="color:#a31515">&quot;18:06:00&quot;</span>,&nbsp;<span style="color:#a31515">&quot;18:07:00&quot;</span>)<span style="color:green">//&nbsp;calling&nbsp;the&nbsp;base&nbsp;class&nbsp;constructor&nbsp;to&nbsp;supply&nbsp;the&nbsp;schedule&nbsp;for&nbsp;every&nbsp;day.&nbsp;This&nbsp;can&nbsp;be&nbsp;a&nbsp;colleaction&nbsp;of&nbsp;strings&nbsp;or&nbsp;timespan&nbsp;itself.</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
</pre>
In the code above “<b>CustomScheduleDaily”</b> is a custom class inheriting predefined “<b>DailySchedule</b>” class. In the definition of constructor for “<b>CustomScheduleDaily</b>” class we are calling the base class constructor (: base("18:06:00", "18:07:00")) to define the schedule. In this example we have passed the collection of strings. We can also define <b>TimeSpan </b>variables and pass them to the base class constructor.

Once custom class “<b>CustomScheduleDaily</b>” is defined we can use the typeof(<b>CustomScheduleDaily</b>) and add it to the <b>TimerTrigger </b>of the function (<b>CustomTimerJobFunctionDaily</b>) which we want to run on a schedule in the web job.

In the current example the web job will run every day at "18:06:00" &amp; "18:07:00".

Below is how it looks on the Azure Web Job Dashboard.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/1.jpg"><img width="752" height="377" title="1" alt="1" src="https://msdnshared.blob.core.windows.net/media/2018/01/1_thumb.jpg" border="0" /></a>

Example 2. <b>WeeklySchedule</b>


<pre style="font-family:Consolas;font-size:13;color:black;background:white"><span style="color:green">//Class&nbsp;for&nbsp;custom&nbsp;schedule&nbsp;weekly</span>
<span style="color:blue">public</span>&nbsp;<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">CustomScheduleWeekly</span>&nbsp;:&nbsp;<span style="color:#2b91af">WeeklySchedule</span>
{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;CustomScheduleWeekly()
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">TimeSpan</span>&nbsp;ts&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">TimeSpan</span>();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">string</span>[]&nbsp;values&nbsp;=&nbsp;<span style="color:blue">null</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//Iterating&nbsp;through&nbsp;complete&nbsp;appsettings&nbsp;section&nbsp;to&nbsp;get&nbsp;the&nbsp;schedule&nbsp;for&nbsp;all&nbsp;the&nbsp;days&nbsp;and&nbsp;then&nbsp;adding&nbsp;the&nbsp;schedule&nbsp;to&nbsp;the&nbsp;timer&nbsp;trigger&nbsp;for&nbsp;each&nbsp;day.</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:#2b91af">String</span>&nbsp;key&nbsp;<span style="color:blue">in</span>&nbsp;<span style="color:#2b91af">ConfigurationManager</span>.AppSettings.Keys)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>&nbsp;(<span style="color:#2b91af">ConfigurationManager</span>.AppSettings[key]&nbsp;!=&nbsp;<span style="color:blue">null</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">string</span>&nbsp;val&nbsp;=&nbsp;<span style="color:#2b91af">ConfigurationManager</span>.AppSettings[key];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values&nbsp;=&nbsp;val.Split(<span style="color:#a31515">&#039;|&#039;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">switch</span>&nbsp;(key)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//Calling&nbsp;the&nbsp;Add(day,&nbsp;time)&nbsp;method&nbsp;of&nbsp;WeeklySchedule&nbsp;class&nbsp;to&nbsp;add&nbsp;the&nbsp;weekday&nbsp;and&nbsp;time&nbsp;on&nbsp;that&nbsp;weekday&nbsp;to&nbsp;run&nbsp;the&nbsp;webjob.</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Mon&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Monday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Tue&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Tuesday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Wed&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Wednesday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Thu&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Thursday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Fri&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Friday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Sat&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Saturday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Sun&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Sunday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;}
}
<span style="color:green">//&nbsp;This&nbsp;function&nbsp;will&nbsp;get&nbsp;triggered/executed&nbsp;on&nbsp;a&nbsp;custom&nbsp;schedule&nbsp;on&nbsp;weekly&nbsp;basis.&nbsp;</span>
<span style="color:blue">public</span>&nbsp;<span style="color:blue">static</span>&nbsp;<span style="color:blue">void</span>&nbsp;CustomTimerJobFunctionWeekly([<span style="color:#2b91af">TimerTrigger</span>(<span style="color:blue">typeof</span>(<span style="color:#2b91af">CustomScheduleWeekly</span>))]&nbsp;<span style="color:#2b91af">TimerInfo</span>&nbsp;timerInfo)
{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">&quot;CustomTimerJobFunctionWeekly&nbsp;ran&nbsp;at&nbsp;:&nbsp;&quot;</span>&nbsp;+&nbsp;<span style="color:#2b91af">DateTime</span>.UtcNow);
}</pre>

<b>CustomScheduleWeekly </b>has the implementation similar to<b> CustomScheduleDaily.</b>

<b>CustomScheduleWeekly</b>  Inherits WeeklySchedule class. So in the constructor we can add the day of week and time on that particular day when we want to run the webjob. This way we can define different timings on different days easily.

Once the schedule is defined we need to assign the typeof(CustomScheduleWeekly) to the TimerTrigger attribute of the function we want to run in the web job.

In this example the weekly schedule is from Monday to Saturday but every day the timing is different. We can add multiple TimeSpan’s for the same DayOfWeek as well so that on that particular day the job can run multiple times as per the time defined.

One limitation with this approach is we are defining the schedule in the code which means if we change the schedule we need to recompile the Azure Web Jobs every time and redeploy it to Azure.

Below is how it looks on the Azure Web Job Dashboard.

<a href="https://msdnshared.blob.core.windows.net/media/2018/01/2.jpg"><img width="759" height="369" title="2" alt="2" src="https://msdnshared.blob.core.windows.net/media/2018/01/2_thumb.jpg" border="0" /></a>

One way to improve this solution is to read the day and time from the app.config file in the web job code. Complete Sample has been uploaded on the GITHUB repo(<a href="https://github.com/amitxagarwal/Azure-Webjobs-Samples/tree/master/TimerTriggerWebJobCustomSchedule">TimerTriggerWebJobCustomSchedule</a>) <a href="https://github.com/amitxagarwal/Azure-Webjobs-Samples">https://github.com/amitxagarwal/Azure-Webjobs-Samples</a> . An example of Customer weekly class getting the schedule from app.config file is shown below.

<pre style="font-family:Consolas;font-size:13;color:black;background:white"><span style="color:blue">public</span>&nbsp;CustomScheduleWeekly()
{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">TimeSpan</span>&nbsp;ts&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">TimeSpan</span>();
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">string</span>[]&nbsp;values&nbsp;=&nbsp;<span style="color:blue">null</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//Iterating&nbsp;through&nbsp;complete&nbsp;appsettings&nbsp;section&nbsp;to&nbsp;get&nbsp;the&nbsp;schedule&nbsp;for&nbsp;all&nbsp;the&nbsp;days&nbsp;and&nbsp;then&nbsp;adding&nbsp;the&nbsp;schedule&nbsp;to&nbsp;the&nbsp;timer&nbsp;trigger&nbsp;for&nbsp;each&nbsp;day.</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:#2b91af">String</span>&nbsp;key&nbsp;<span style="color:blue">in</span>&nbsp;<span style="color:#2b91af">ConfigurationManager</span>.AppSettings.Keys)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>&nbsp;(<span style="color:#2b91af">ConfigurationManager</span>.AppSettings[key]&nbsp;!=&nbsp;<span style="color:blue">null</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">string</span>&nbsp;val&nbsp;=&nbsp;<span style="color:#2b91af">ConfigurationManager</span>.AppSettings[key];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values&nbsp;=&nbsp;val.Split(<span style="color:#a31515">&#039;|&#039;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">switch</span>&nbsp;(key)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//Calling&nbsp;the&nbsp;Add(day,&nbsp;time)&nbsp;method&nbsp;of&nbsp;WeeklySchedule&nbsp;class&nbsp;to&nbsp;add&nbsp;the&nbsp;weekday&nbsp;and&nbsp;time&nbsp;on&nbsp;that&nbsp;weekday&nbsp;to&nbsp;run&nbsp;the&nbsp;webjob.</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Mon&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Monday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Tue&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Tuesday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Wed&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Wednesday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Thu&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Thursday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Fri&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Friday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Sat&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Saturday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">case</span>&nbsp;<span style="color:#a31515">&quot;Sun&quot;</span>:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">string</span>&nbsp;val&nbsp;<span style="color:blue">in</span>&nbsp;values)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ts&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Parse(val).TimeOfDay;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Add(<span style="color:#2b91af">DayOfWeek</span>.Sunday,&nbsp;ts);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">break</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;}
 
}</pre>

Here is the appsettings section from app.config.

<pre style="font-family:Consolas;font-size:13;color:black;background:white"><span style="color:blue">&nbsp;&nbsp;&lt;</span><span style="color:#a31515">appSettings</span><span style="color:blue">&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Mon</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">08:11:20|09:24:20|09:28:20</span>&quot;<span style="color:blue">/&gt;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Tue</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">09:19:40</span>&quot;<span style="color:blue">/&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Wed</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">09:15:40</span>&quot;<span style="color:blue">/&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Thu</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">09:15:40</span>&quot;<span style="color:blue">/&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Fri</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">09:15:40</span>&quot;<span style="color:blue">/&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Sat</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">09:15:40</span>&quot;<span style="color:blue">/&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&nbsp;&nbsp;&lt;</span><span style="color:#a31515">add</span><span style="color:blue">&nbsp;</span><span style="color:red">key</span><span style="color:blue">=</span>&quot;<span style="color:blue">Sun</span>&quot;<span style="color:blue">&nbsp;</span><span style="color:red">value</span><span style="color:blue">=</span>&quot;<span style="color:blue">09:15:40</span>&quot;<span style="color:blue">/&gt;</span>
<span style="color:blue">&nbsp;&nbsp;&lt;/</span><span style="color:#a31515">appSettings</span><span style="color:blue">&gt;</span></pre>

This is just another “<b>easy</b> ”way of defining the schedule programmatically. However the CRON Expressions are still the CRISP way of defining the schedule, may be tricky though.]]></content:encoded>
    </item>
    <item>
      <title>Azure Function Apps: “Unable to retrieve the Master/Runtime keys” OR “The function runtime is unable to start”.</title>
      <link>https://docs.microsoft.com/archive/blogs/amitagarwal/we-are-unable-to-retrieve-the-master-runtime-keys-for-azure-function-app</link>
      <pubDate>Mon, 20 Nov 2017 16:32:26 GMT</pubDate>
      <dc:creator><![CDATA[Amit Agarwal (amagar)]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/amitagarwal/?p=25</guid>
      <description><![CDATA[While working with Azure Functions users might encounter error in the Azure portal while clicking...]]></description>
      <content:encoded><![CDATA[<p><br></p>
<p>While working with Azure Functions users might encounter error in the Azure portal while clicking on a Function App. You might see one of these errors in the upper right hand corner of the portal:</p>
<p><strong>“We are not able to retrieve the keys for function”</strong></p>
<p>or</p>
<p><strong>“We are not able to retrieve the master key for function”</strong>.</p>
<p>or</p>
<p><strong>“The function runtime is unable to start. Please check the runtime logs for any errors or try again later.”</strong><strong></strong></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/01/17.jpg"><img width="343" height="207" title="1" style="border: 0px currentcolor" alt="1" src="https://msdnshared.blob.core.windows.net/media/2018/01/1_thumb4.jpg" border="0"></a>&nbsp;&nbsp; <a href="https://msdnshared.blob.core.windows.net/media/2018/01/27.jpg"><img width="350" height="206" title="2" style="border: 0px currentcolor" alt="2" src="https://msdnshared.blob.core.windows.net/media/2018/01/2_thumb4.jpg" border="0"></a></p>
<p><strong>In this post, we will discuss s</strong>ymptoms of the error, the cause and how to resolve the issue.</p>
<p><strong></strong></p>
<p><strong><u>Symptoms</u></strong><u></u></p>
<p>Every function app has a default Admin/Master and function keys. This is visible under the “<strong>Manage</strong>” section of a Function app as shown below. When the portal starts to load, an API call is made to populate the keys. If these API calls fail then it would result in the following error on the portal:</p>
<p>“We cannot retrieve the runtime master key” or “We are unable to retrieve the keys for the function” or “The function runtime is unable to start. Please check the runtime logs for any errors or try again later.”</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/01/34.jpg"><img width="726" height="317" title="3" style="border: 0px currentcolor" alt="3" src="https://msdnshared.blob.core.windows.net/media/2018/01/3_thumb3.jpg" border="0"></a></p>
<p>Also, in most of the cases you may also see nothing being populated under the <strong>Manage </strong><strong>section. It might </strong><strong>look like this.</strong><strong></strong></p>
<p><strong></strong></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/01/44.jpg"><img width="732" height="323" title="4" style="border: 0px currentcolor" alt="4" src="https://msdnshared.blob.core.windows.net/media/2018/01/4_thumb1.jpg" border="0"></a></p>
<p><strong><u>Cause</u></strong><strong><u></u></strong></p>
<p>The API calls can fail due to several reasons. Here are few of them:</p>
<ul>
<li>
<div>Issues with the application code/Compilation errors/Runtime issues.</div>
</li>
<li>
<div>Function apps <b>host.json</b>/<b>function.json</b> contains incorrect settings.</div>
</li>
<li>
<div>“<strong>AzureWebJobsDashboard</strong>” and “<strong>AzureWebJobsStorage</strong>” app setting in the portal is missing or is pointing to an invalid storage account.</div>
</li>
<li>
<div>Other functions under one function app might have issues and can affect other functions under the same function app. This can impact the function app host.</div>
</li>
<li>
<div>Function app using <b>consumption plan</b> has quota restrictions on usage of system resources of the underlying VM. Below is the <a href="https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox">list </a>of limits which are imposed on the consumption plan.</div>
</li>
</ul>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://msdnshared.blob.core.windows.net/media/2017/11/image349.png"><img width="613" height="149" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/11/image_thumb290.png" border="0"></a></p>
<ul></ul>
<p><br></p>
<ul></ul>
<p><strong><u>Resolution</u></strong><strong><u></u></strong></p>
<p>Here are few ways on this issue can be addressed:</p>
<p>1. If you suspect the application code, then</p>
<ol>
<li style="list-style-type: none">
<ul>
<li>browse the <b>KUDU</b> site of your function app.</li>
<li>Under <b>Process Explorer</b>, right click and kill the W3WP.exe process.</li>
</ul>
</li>
</ol>
<p>This will trigger a restart of the process and also this will result in a compilation of the code by the Functions runtime. Any error (code/compilation) would be visible under the Logs window (lower half ) of the Function app.</p>
<p>2. The function running under <b>Consumption plan</b> is creating too many outbound connections. Under such scenarios, is advisable to ensure the connections are disposed of appropriately.</p>
<p>If these connections are expected to take more time to respond, then it may hit the <b>connections</b> quota limit described above.</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="733"><b>NOTE</b>: For such scenarios it is advisable to switch to Dedicated App Service Plan to run your function app. The function app will have to be re-created and re-deployed as switching of ASP from consumption plan to dedicated plan is currently not available.</td>
</tr>
</tbody>
</table>
<p>Ensure that the functions are not running any intensive task on a consumption plan. This may cause it hit other restrictions which are described above.</p>
<p>3. If the settings inside Function.json or Host.json is misspelled or if there is any additional character, then this can cause the above-mentioned error. Please review the files and ensure that we have the right entries.</p>
<p>4. Adding property “functions” in <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json">host.json</a> to selectively enable few functions will cause the other functions to throw this error. Either add all the functions here or if there is a need of disabling few and enabling the rest then disable the functions from the UI is a preferred method.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/01/54.jpg"><img width="565" height="729" title="5" style="border: 0px currentcolor" alt="5" src="https://msdnshared.blob.core.windows.net/media/2018/01/5_thumb1.jpg" border="0"></a></p>
<p>5. Ensure that the app settings for “<strong>AzureWebJobsDashboard</strong>” and “<strong>AzureWebJobsStorage</strong>” are present and have been set to use the correct storage account. Check the credentials too.</p>
<p><strong><u>MORE INFORMATION</u></strong></p>
<p>If you try to add the function keys manually then you might see another error as shown below:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/2018/01/clip_image00244.jpg"><img width="475" height="295" title="clip_image002[4]" style="border: 0px currentcolor" alt="clip_image002[4]" src="https://msdnshared.blob.core.windows.net/media/2018/01/clip_image0024_thumb4.jpg" border="0"></a></p>
<p>If nothing works, then contact <b>Azure App Services</b> Support team.</p>]]></content:encoded>
    </item>
  </channel>
</rss>