Specify Hangfire Queue in BackgroundJob Calling Method

Is there a way to specify the name of the queue when calling the method and not having to add an attribute to the method? I have a legacy class library that is compiled against .NET 3.5 and cannot update to .NET 4.5 to install Hangfire.Core in order to add the attribute [Queue("critical")] to the call of the method.

I have 2 queues, 1 that is “critical” and one that is “default”. I want this one method to always use this specific queue to process.

Is there a way to specify the queue in this way? If not, can it be added to handle this situation?

var processor = new MyClassInDotNet35();
BackgroundJob.Enqueue(() => processor.Run(DateTime.UtcNow), "critical");

Yep, Hangfire itself is a disguised state machine, you can specify the queue at runtime in the following way:

using Hangfire;
using Hangfire.States;

var client = new BackgroundJobClient();
var state = new EnqueuedState("your-queue");

client.Create(() => Console.WriteLine("Hi!"), state);
1 Like

Thank you, I couldn’t find this anywhere in the documentation.

What about scheduling a job to run on a specific queue? I don’t see an overload to include the EnqueuedState object.

Yep, a lot of things aren’t documented yet. There is no possibility to use another queue for scheduled jobs so far, but you can simply write a wrapper method:

// Old method
BackgroundJob.Enqueue(() => Console.WriteLine("Old"))

// New method
[Queue("critical")]
public static void CustomWriteLine(string value) 
{ 
    Console.WriteLine(value);
}

BackgroundJob.Enqueue(() => CustomWriteLine("New"));

@odinserj

I have a shared hangfire database, one application queues job in default queue, others have their specific queues.
If I use BankgroundJob.Enqueue it respects queue and assigns accordingly. However when I use BackgroundJob.Schedule in a specific queue, it is being picked by any of all executors irrespective of queue name.

The version I am using is 1.6.9. Please suggest any workaround.

Thank you
Najam

1 Like

Hi!

What if my queue name is dynamic? It would be hard (if not impossible) to dynamically add an attribute to my wrapper method.

Is there another way to Schedule a job to a specific queue?

Thank you.

What I ended up doing was I schedule I job to enqueue job on a specific queue. It’s not ideal, but it’s been working.

So I do something like

BackgroundJob.Schedule(() => ForceTheQForWhateverJob(info), TimeSpan.FromMonutes(30));

then that method just does:

void ForceTheQForWhateverJob(object info) {
    var client = new BackgroundJobClient();
    client.Create(DoSomethingWithMyParmeters(info), new EnqueuedState("QUEUE_NAME"));
}

I managed to queue and schedule a job in a specific queue by adding a custom filter provider. I can choose in which queue to get it executed based on the Job data.

JobFilterProviders.Providers.Add(new CustomJobFilterProvider());

public class  CustomJobFilterProvider: IJobFilterProvider
{
    public IEnumerable<JobFilter> GetFilters(Job job)
    {
        String queueName = GetQueueName(job);
        return new JobFilter[]
        {
            new JobFilter(

                new QueueAttribute(queueName),
                JobFilterScope.Method, null
            )
        };
    }

    String GetQueueName(Job job)
    {
        return "myqueue";
    }
}
2 Likes

Great solution. Worked a treat for me!

Hi All,
Another workaround for this problem is:

var options = new BackgroundJobServerOptions
{
Queues = new[] { “**UNIQUE JOB NAME for JOB 1”, “default” , “**UNIQUE JOB NAME for JOB 2”, “xyz”} // Add as many jobs as you want - just follow the sample and then add it in the JSON file
};
appBuilder.UseHangfireServer(options);
GlobalConfiguration.Configuration.UseRecurringJob(".json");
GlobalConfiguration.Configuration.UseDefaultActivator();
/////////////////////////////////////////////////
My JSON file is:

[
{
“job-name”: “NAME 2”,
“job-type”: “PROGRAM.CLASSNAME1, PROGRAM”,
// “cron-expression”: “*/5 * * * *”,
“cron-expression”: “5 10 * * fri”,
//“cron-expression”: “5 6 * * mon”,
“timezone”: “YOUR TIME ZONE”,
“queue”: “**UNIQUE JOB NAME for JOB 1
},
{
“job-name”: “NAME 2”,
“job-type”: “PROGRAM.CLASSNAME2, PROGRAM”,
“cron-expression”: “5 11 * * fri”,
//“cron-expression”: “15 6 * * mon”,
“timezone”: “YOUR TIME ZONE”,
“queue”: “**UNIQUE JOB NAME for JOB 2
}
]

You made my day. Thanks!