Saturday, October 4, 2014

Scheduled Tasks in NServiceBus

One of the nicest things that can be done using NServiceBus is we can schedule a task or an action/lambda, to be executed repeatedly. In this post let’s see it in action in which I am going to periodically send messages from one NServiceBus to another NServiceBus host.

I will start  off with the application by creating a blank solution named “NServiceBusScheduledTaskSample”.

image
Blank Solution
For this solution, I am adding three class library projects named “NServiceBusScheduledTaskSample.Server”, “NServiceBusScheduledTaskSample.Client” and “NServiceBusScheduledTaskSample.Messages”. “NServiceBusScheduledTaskSample.Server” project is responsible for sending messages to “NServiceBusScheduledTaskSample.Client”. I am deleting default Class1.cs from all the three projects. Now I am running NServiceBus.Host nuget package on “NServiceBusScheduledTaskSample.Server” and “NServiceBusScheduledTaskSample.Client” projects using Package Manager Console.

Install on Server

image
Install on Server
Install on Client

image
Install on Client
Once Package Manager Console completed installing all the required files, you can see in both “NServiceBusScheduledTaskSample.Server” and “NServiceBusScheduledTaskSample.Client” projects, there is a new class added named “EndpointConfig”.

Now let’s move into Server Project. I am keeping the “EndpointConfig” class as it is. If you are running scheduled tasks, inherting “EndpointConfig” from AsA_Server or AsA_Publisher is a must. Because if your “EndpointConfig” inherits from AsA_Client, then the TimeoutManager is disabled and we need that to run scheduled tasks. So after keeping “EndpointConfig” as it is, I am adding a new class to the project and I am naming it as “MyTask”. I am implementing an interface named “IWantToRunWhenBusStartsAndStops” on “MyTask”.
public class MyTask : IWantToRunWhenBusStartsAndStops
{
    public IBus Bus { get; set; }

    public void Start()
    {
 
    }
 
    public void Stop()
    {
 
    }
}
Now here in “Start()”, I am planning on sending messages to my Client project. For that between the Server and Client, I need to share messages. Those messages, I am going to put in Messages Project. I am adding a new class named “MyMessage” inside Messages project. “MyMessage” is implementing “ICommand”.

There I have a single property named “Message” of type string.
using NServiceBus;

namespace NServiceBusScheduledTaskSample.Messages
{
    public class MyMessage : ICommand
    {
        public string Message { get; set; }
    }
}
After doing that, I am going to add references from both Server and Client to Messages project.

Again moving back to Server project, I am modifying the “Start()” method in “MyTask” as follows.
public void Start()
{
    Schedule.Every(TimeSpan.FromSeconds(5)).Action(() =>
    {
        Bus.Send("NServiceBusScheduledTaskSample.Client", new MyMessage()
        {
            Message = "Hello World!"
        });
        Console.WriteLine("Sent a message.");
    });
}
Schedule is a static class that can be accessed anywhere (in Version 4.x). So I am Scheduling a action in which I am doing a Bus.Send for every 5 seconds and as it’s parameters, I am passing my destination and my message to be sent.

Now inside my Client project, I am modifying the “EndpointConfig” as  follows.
public class EndpointConfig : IConfigureThisEndpoint, AsA_Client
{
}
Instead of AsA_Server, I have changed it to AsA_Client. I can keep it as AsA_Server, it will still work here.

Now I am adding a new class named “MessageReceiver”. I am implementing an interface named “IHandleMessages<T>” on “MessageReceiver”. In this case it’s “IHandleMessages<MyMessage>”.
public class MessageReceiver : IHandleMessages<MyMessage>
{
    public void Handle(MyMessage message)
    {
        Console.WriteLine(message.Message);
    }
}
Now I am all set. Now since I need to run multiple projects, I am selecting multiple startup projects.

image_thumb19
Setting Startup Projects
Now when I run the project, I am getting the following.
image
Result
I am uploading the full sample to my OneDrive.


Happy Coding.

Regards,
Jaliya