You can use a DurableFunction, in which you pass your desired scheduled-datetime. The DurableFunction can be called from any normal azure function (e.g. HttpTrigger-Function).
To achieve the functionality, the DurableFunction uses CreateTimer, which waits, until the DateTime is reached.
It is made up of three parts
- A DurableFunction (orchestration)
- An Activity, which is called from the DurableFunction
- A normal HttpTrigger-Function which calls the DurableFunction and passes the desired ScheduleTime to the DurableFunction
Here the full code, which you can use by calling the normal Azure Function. In my case it is http://localhost:7071/api/RaiseScheduledEvent_HttpStart.
To have the sample running in VisualStudio, please make sure you have the following setting in your local.settings.json:
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace api
{
public class RaiseEventParameter
{
public DateTime RaiseAt { get; set; }
}
public static class RaiseScheduledEvent
{
// This is the DurableFunction, which takes the ScheduledTime (RaiseAt) as parameter
[FunctionName("RaiseScheduledEvent")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var raiseAt = context.GetInput<RaiseEventParameter>().RaiseAt;
await context.CreateTimer(raiseAt, CancellationToken.None);
await context.CallActivityAsync("RaiseScheduledEvent_TimerElapsed", null);
}
// When the timer elapsed, the below activity is called.
// Here you can do, whatever you planned at the scheduled-time
[FunctionName("RaiseScheduledEvent_TimerElapsed")]
public static void TimerElapsed([ActivityTrigger] object input, ILogger log)
{
Console.WriteLine("Elapsed at " + DateTime.UtcNow.ToString());
}
// This is the normal Http-Trigger function, which calls the durable function
// Instead of hardcoding the RaiseAt, you could use any input of your Azure Function
[FunctionName("RaiseScheduledEvent_HttpStart")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
var parameter = new RaiseEventParameter()
{
RaiseAt = DateTime.UtcNow.AddSeconds(5)
};
string instanceId = await starter.StartNewAsync("RaiseScheduledEvent", parameter);
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
}