# Schedule Messages
# From a Consumer
To schedule messages from a consumer, use any of the ConsumeContext extension methods, such as ScheduleSend, to schedule messages.
namespace SchedulingConsumeContext
{
using System;
using System.Threading.Tasks;
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main()
{
var services = new ServiceCollection();
Uri schedulerEndpoint = new Uri("queue:scheduler");
services.AddMassTransit(x =>
{
x.AddMessageScheduler(schedulerEndpoint);
x.AddConsumer<ScheduleNotificationConsumer>();
x.UsingRabbitMq((context, cfg) =>
{
cfg.UseMessageScheduler(schedulerEndpoint);
cfg.ConfigureEndpoints(context);
});
});
}
}
public class ScheduleNotificationConsumer :
IConsumer<ScheduleNotification>
{
public async Task Consume(ConsumeContext<ScheduleNotification> context)
{
Uri notificationService = new Uri("queue:notification-service");
await context.ScheduleSend<SendNotification>(notificationService,
context.Message.DeliveryTime,
new
{
EmailAddress = context.Message.EmailAddress,
Body = context.Message.Body
});
}
class SendNotificationCommand :
SendNotification
{
public string EmailAddress { get; set; }
public string Body { get; set; }
}
}
public interface ScheduleNotification
{
DateTime DeliveryTime { get; }
string EmailAddress { get; }
string Body { get; }
}
public interface SendNotification
{
string EmailAddress { get; }
string Body { get; }
}
}
The message scheduler, specified during bus configuration, will be used to schedule the message.
# From a Bus
To schedule messages from a bus, use IMessageScheduler from the container (or create a new one using the bus and appropriate scheduler).
namespace SchedulingScheduler
{
using System;
using System.Threading.Tasks;
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static async Task Main()
{
var services = new ServiceCollection();
Uri schedulerEndpoint = new Uri("queue:scheduler");
services.AddMassTransit(x =>
{
x.AddMessageScheduler(schedulerEndpoint);
x.UsingRabbitMq((context, cfg) =>
{
cfg.UseMessageScheduler(schedulerEndpoint);
cfg.ConfigureEndpoints(context);
});
});
var provider = services.BuildServiceProvider();
var scheduler = provider.GetRequiredService<IMessageScheduler>();
await scheduler.SchedulePublish<SendNotification>(
DateTime.UtcNow + TimeSpan.FromSeconds(30), new
{
EmailAddress = "frank@nul.org",
Body = "Thank you for signing up for our awesome newsletter!"
});
}
}
public interface SendNotification
{
string EmailAddress { get; }
string Body { get; }
}
}
# Recurring Messages
You can also schedule a message to be send to you periodically. This functionality uses the Quartz.Net periodic schedule feature and requires some knowledge of cron expressions.
To request a recurring message, you need to use ScheduleRecurringSend
extension method, which is available
for both Context
and SendEndpoint
. This message requires a schedule object as a parameter, which must
implement RecurringSchedule
interface. Since this interface is rather broad, you can use the default
abstract implementation DefaultRecurringSchedule
as the base class for your own schedule.
public class PollExternalSystemSchedule : DefaultRecurringSchedule
{
public PollExternalSystemSchedule()
{
CronExpression = "0 0/1 * 1/1 * ? *"; // this means every minute
}
}
public class PollExternalSystem {}
var schedulerEndpoint = await bus.GetSendEndpoint(_schedulerAddress);
var scheduledRecurringMessage = await schedulerEndpoint.ScheduleRecurringSend(
InputQueueAddress, new PollExternalSystemSchedule(), new PollExternalSystem());
When you stop your service or just have any other need to tell Quartz service to stop sending you
these recurring messages, you can use the return value of ScheduleRecurringSend
to cancel the recurring schedule.
await bus.CancelScheduledRecurringMessage(scheduledRecurringMessage);
You can also cancel using schedule id and schedule group values, which are part of the recurring schedule object.