43

I have a console application to test HangFire. Here is the code:

using System;
using Hangfire;

namespace MyScheduler.ConsoleApp
{
    internal static class Program
    {
        internal static void Main(string[] args)
        {
            MyMethod();

            Console.WriteLine("[Finished]");
            Console.ReadKey();
        }

        private static void MyMethod()
        {
            RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Minutely);
        }
    }
}

But it throws an exception on runtime:

Additional information: JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.

So I need a job storage to run this. But all examples in SQL storage etc. Is there any way to run this example with some kind of memory storage?

JobStorage.Current = new SqlServerStorage("ConnectionStringName", options);  
// to  
JobStorage.Current = new MemoryDbStorage(string.Empty, options);  
mason
  • 31,774
  • 10
  • 77
  • 121
Lost_In_Library
  • 3,265
  • 6
  • 38
  • 70
  • Did you try doing a Google search for "Hangfire memory"? I found the answer to your question in under 10 seconds. And even if you decide that doesn't work for you, there's plenty of other options that are easy to set up such as SQL Server LocalDB, SQLite, and Mongo. – mason Apr 04 '17 at 12:11
  • 1
    I updated my question. And documention should be updated too. Have a nice day. – Lost_In_Library Apr 04 '17 at 12:28
  • NuGet's search feature isn't so good. Use Google/Bing. Anyways, there's no need to tell *us* about the documentation. You can submit a pull request to update it or raise an issue on their [GitHub](https://github.com/HangfireIO/Hangfire-Documentation). Anyways, I think their documentation there is fine. If you read it, "Hangfire.Core is enough" is clearly referring to not installing the main "Hangfire" package which has dependencies not needed by a console app. And right above that it clearly states you need a job storage package. It's pretty clear to me. – mason Apr 04 '17 at 13:01
  • I didn't edit your answer. You don't have an answer! You have a question. Questions posts are for questions, answer posts are for answers. That's just how we try to keep things clean on Stack Overflow. What you had edited into your question wasn't part of the question (and wasn't an solution either), just some thoughts that fit better into a comment. That's why I edited it out - to keep your question clean and focused on the issue. – mason Apr 04 '17 at 13:32
  • I did read the documentation you linked to - I've read over that page myself a few times, having used Hangfire in several projects. The documentation is clear enough to me. It states use Hangfire.Core, not Hangfire. And it states you need a job storage package. That's straightforward enough. But if you disagree, Stack Overflow is *not* the place to vent your disagreement. If you want the documentation updated, then you can either do it yourself or request that someone do it by filing an issue on their GitHub repo. Stating "someone should update it" here is just noise. Focus on the issue! – mason Apr 04 '17 at 13:35
  • I see you've edited that text back into your question, even after my explanation. Rather than me unilaterally reverting it, perhaps you should state *why* you think it belongs in your question? – mason Apr 04 '17 at 13:36

5 Answers5

67

You can use Hangfire.MemoryStorage for this.

Simply add this nuget package.

And then you can use it like -

GlobalConfiguration.Configuration.UseMemoryStorage();
Yogi
  • 9,174
  • 2
  • 46
  • 61
  • 2
    @mason: Yup, heard that :), but just in case..., may be he got confused or kind of, i dont know. but he posted the q., which is more effort than a google search, so i thought probably he needed answer from us :) – Yogi Apr 04 '17 at 12:27
  • 2
    As the author notices, memory storage is not supposed to be in a production environment. – Karel Kral Mar 01 '19 at 08:59
  • I want to utilize Hangfire for a continuous background job, and I don't want to store anything anywhere. I have my own logs. I don't want the in memory storage either, because my app is memory sensitive. What options do I have? – Vin Shahrdar Jun 25 '21 at 22:35
  • @VinShahrdar - This is not possible with HF, because HF by design require storage. Having said that, you can make HF runs as a separate application, so it will not affect your main app. – Yogi Jun 26 '21 at 08:19
  • @Yogi I cannot use it as a separate app. I know it goes against the best practices, but my requirement is to spin up a single thread upon application initialization, and in this thread, I want to do a continuous file sync between a source and a destination. You think I should go with just a simple threading code? – Vin Shahrdar Jun 28 '21 at 03:13
  • @VinShahrdar, yeah in case you may use Task Parallel Library (TPL). (https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl) – Yogi Jun 28 '21 at 03:29
41

For NET Core (web application):

Just to make it very obvious because it wasn't obvious to me.

Install following nuget packages:

  • Hangfire.AspNetCore (v1.6.17 atow)
  • Hangfire.MemoryStorage.Core (v1.4.0 atow)

In Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        // other registered services
        ...

        services.AddHangfire(c => c.UseMemoryStorage());
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // other pipeline configuration            
        ...

        app.UseHangfireServer();

        app.UseMvc();
    }

Anything less than above and my enqueued method did not fire.

Quinton Smith
  • 2,550
  • 18
  • 17
  • 6
    And to make it super-duper obvious: don't forget the using Hangfire and using Hangfire.MemoryStorage declarations. – Ian Oct 25 '19 at 19:21
7

Just for the sake of completeness the author of the Hangfire library has added a new package titled Hangfire.InMemory the version of which is available on Nuget. The repository readme positions it as targeting production use. A quote github repo URL is as follows "..an efficient transactional in-memory storage for Hangfire with data structures close to their optimal representation. The result of this attempt should enable production-ready usage of this storage implementation and handle particular properties of in-memory processing.."

The familiar configuration concept applies here as well: GlobalConfiguration.Configuration.UseInMemoryStorage();

I personally added it as follows: services.AddHangfire(configuration => { configuration.UseInMemoryStorage(); });

timmi4sa
  • 594
  • 6
  • 15
6

As Yogi said, you can use Hangfire.MemoryStorage or Hangfire.MemoryStorage.Core (for .Net Core).

What is missing in that answer is the complete code (for .Net Core) that needs to be put inside ConfigureServices(..) :

var inMemory = GlobalConfiguration.Configuration.UseMemoryStorage();
services.AddHangfire(x => x.UseStorage(inMemory));
goamn
  • 1,939
  • 2
  • 23
  • 39
0

For in-memory with a .NET 6 console app (as a Windows Service), I use the following which also has the dashboard configured, should you wish to use it:

using Hangfire;
using Hangfire.Services;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

await Host
    .CreateDefaultBuilder()
    .ConfigureWebHostDefaults(builder =>
    {
        builder.Configure(app =>
        {
            app.UseHangfireDashboard();

            RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Minutely);
        });
    })
    .UseWindowsService()
    .ConfigureServices(services =>
    {
        services.AddHangfire(opt =>
        {
            opt.UseInMemoryStorage();
        });

        services.AddHangfireServer();
    })
    .Build()
    .RunAsync();

This is using the official package from Hangfire - https://github.com/HangfireIO/Hangfire.InMemory

Ben D
  • 669
  • 1
  • 11
  • 19