<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sipke Schoorstra</title>
    <description>The latest articles on DEV Community by Sipke Schoorstra (@sfmskywalker).</description>
    <link>https://dev.to/sfmskywalker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F175737%2Fe977f766-0308-41ce-8982-a457939e9dc5.jpeg</url>
      <title>DEV Community: Sipke Schoorstra</title>
      <link>https://dev.to/sfmskywalker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sfmskywalker"/>
    <language>en</language>
    <item>
      <title>Scheduled Background Tasks made easy with Elsa Workflows</title>
      <dc:creator>Sipke Schoorstra</dc:creator>
      <pubDate>Sun, 06 Dec 2020 20:21:45 +0000</pubDate>
      <link>https://dev.to/sfmskywalker/scheduled-background-tasks-made-easy-with-elsa-workflows-3o6k</link>
      <guid>https://dev.to/sfmskywalker/scheduled-background-tasks-made-easy-with-elsa-workflows-3o6k</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F08ue6x1inu6fkvhdsuin.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F08ue6x1inu6fkvhdsuin.jpg" alt="Photo by Estée Janssens"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@esteejanssens" rel="noopener noreferrer"&gt;Estée Janssens&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Implementing background tasks could hardly be any simpler with ASP.NET Core today. But when it comes to scheduling background tasks, what do you do?&lt;/p&gt;

&lt;p&gt;As it turns out, you have a number of very attractive options available to you. Specifically, I’m thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ASP.NET Core Hosted Service&lt;/li&gt;
&lt;li&gt;Quartz.NET&lt;/li&gt;
&lt;li&gt;Elsa Workflows (the reason you are reading this post)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll take a brief look at each of these options and see how they compare.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hosted Service
&lt;/h2&gt;

&lt;p&gt;If all you need is a recurring task that executes at a set interval, the simplest option (without taking on any external package dependencies) might be to implement a Hosted Service and perform work in an infinite loop until the cancellation token is triggered.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is perfectly fine for performing work in the background at a specific interval. But what if you want to schedule work using more advanced schedules, like using a cron schedule?&lt;/p&gt;

&lt;p&gt;As demonstrated in &lt;a href="https://codeburst.io/schedule-cron-jobs-using-hostedservice-in-asp-net-core-e17c47ba06" rel="noopener noreferrer"&gt;this article&lt;/a&gt;, you might implement that as a hosted service yourself. But it does require quite a bit of code.&lt;/p&gt;

&lt;p&gt;So what about Quartz.NET?&lt;/p&gt;

&lt;h2&gt;
  
  
  Quartz.NET
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.quartz-scheduler.net/" rel="noopener noreferrer"&gt;Quartz.NET&lt;/a&gt; is an open source scheduling system for .NET that is flexible and easy to use. It offers many features that makes scheduling jobs super-easy.&lt;/p&gt;

&lt;p&gt;With Quartz.NET, you get all sorts of scheduling options in the form of triggers, which include simple triggers and cron triggers.&lt;/p&gt;

&lt;p&gt;To implement a job that executes on a given schedule, all you need to do is implement a Job class that performs the work, register it with Quartz, and then schedule it using one or more triggers.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This might be all you need to implement scheduled jobs.&lt;/p&gt;

&lt;p&gt;But there’s a third option that makes this easier, more flexible and even more powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Elsa Workflows
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/elsa-workflows/elsa-core/tree/feature/elsa-2.0" rel="noopener noreferrer"&gt;Elsa Workflows&lt;/a&gt; is an open source library for .NET that enables applications to implement both short-running and long-running workflows, either in code, using a designer, or both.&lt;/p&gt;

&lt;p&gt;Even if you have zero interest in working with workflow systems and designers, Elsa comes with an easy to use API to implement background tasks.&lt;/p&gt;

&lt;p&gt;The Elsa equivalent of a Hosted Service in .NET Core and a Job in Quartz.NET is the &lt;strong&gt;Workflow&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a matter of fact, Elsa Workflows’ scheduling mechanism directly uses Quartz.NET to schedule work at a given time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To implement a workflow, all you have to do is implement &lt;code&gt;IWorkflow&lt;/code&gt; and register it with DI. That’s it.&lt;/p&gt;

&lt;p&gt;For example, to implement a scheduled job, you could create the following workflow:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And then register it with DI like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddElsa&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseConsoleActivities&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseTimerActivities&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddWorkflow&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Yep, that’s pretty easy.&lt;/p&gt;

&lt;p&gt;Of course, most background jobs will do a little bit more than just printing the current date and time to the console. For example, you may want to clean out the trash every &lt;em&gt;Monday morning at 08:00&lt;/em&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Looks pretty neat!&lt;/p&gt;

&lt;p&gt;Not only does Elsa simplify declaring scheduled tasks with this simple API, it automatically opens the door for you to implement actual workflow stuff (since after all, this is a real workflow!).&lt;/p&gt;

&lt;p&gt;For instance, after cleaning out the trash, you may want to sleep for a while, walk the dog and do some dishes, perhaps something like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Notice that in this version of the workflow, there are two time-based triggers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cron (which starts the workflow ever Monday morning at 08:00)&lt;/li&gt;
&lt;li&gt;Timer (which starts ticking after the trash has been cleaned).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Implementing this with Quartz.NET would require you to manually schedule a new job, possibly from some event handler raised by the clean up service. Doable, but increasingly harder to follow as complexity increases.&lt;/p&gt;

&lt;p&gt;And of course it would be quite sad for the dog to be walked on Monday mornings only. Fortunately Elsa makes it easy to fix that by just declaring another workflow class that takes good care of the dog.&lt;/p&gt;

&lt;p&gt;To learn more about Elsa, checkout the &lt;a href="https://github.com/elsa-workflows/elsa-core/tree/feature/elsa-2.0" rel="noopener noreferrer"&gt;project on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: the Elsa-related code described in this article targets Elsa 2.0-preview.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;So there you have it! We looked at 3 viable options of implementing scheduled tasks in .NET Core / .NET 5.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Hosted Service&lt;/strong&gt; option is great for simple, recurring schedules and requires no external packages. But if you want cron schedules, you better pull up your sleeves and start writing some code.&lt;/p&gt;

&lt;p&gt;Next, we looked at &lt;strong&gt;Quartz.NET&lt;/strong&gt;, which I think is pretty awesome for implementing background tasks.&lt;/p&gt;

&lt;p&gt;Finally, we looked at &lt;strong&gt;Elsa Workflows&lt;/strong&gt;, which I think is another great choice to make implementing background tasks a real breeze. And being a workflow, it automatically enables you to implement more complex, long-running process flows, where you can mix &amp;amp; match any kind of trigger beyond time-based events. Examples include service bus messages, HTTP requests, application-specific events, and virtually anything you can dream up.&lt;/p&gt;

</description>
      <category>aspnetcore</category>
      <category>elsa</category>
      <category>quartz</category>
      <category>workflow</category>
    </item>
  </channel>
</rss>
