I’m doing a Fire-and-Forget method invocation like this.
BackgroundJob.Enqueue(() => SendEmail(name));
I would like to use the job id inside the SendEmail() method. Is it possible?
I’m doing a Fire-and-Forget method invocation like this.
BackgroundJob.Enqueue(() => SendEmail(name));
I would like to use the job id inside the SendEmail() method. Is it possible?
You can set up a filter class like this:
public class GetJobId : JobFilterAttribute,
IClientFilter, IServerFilter, IElectStateFilter, IApplyStateFilter
{
[ThreadStatic]
private static string _jobId;
public static string JobId { get { return _jobId; } set { _jobId = value; } }
public void OnPerforming(PerformingContext filterContext)
{
_jobId = filterContext.BackgroundJob.Id;
}
}
And your method like:
[GetJobId ()]
public void SendEmail(string name)
{
string jobId = GetJobId.JobId;
}
Hope this help.
First, never use a static field for that, even if marked with a ThreadStaticAttribute
. The job could be executed on a different thread (for example, Task-based jobs), and you’ll get an empty result.
For achieving your goal, just add PerformContext
to your job method:
public void SendEmail(string name, PerformContext context)
{
string jobId = context.BackgroundJob.Id;
}
And pass null
for it when enqueuing a job:
BackgroundJob.Enqueue(() => SendEmail(name, null));
It will be substituted with a correct context when the job is actually performed.
Another idea is to hook into the activation of the job (when the instance of the job object is constructed) and inject in the job id as a property. I’ve been messing around with this idea via https://github.com/Silvenga/Hangfire.ActivationExtensions (still beta, but simple enough).
Considering your job implements the interface (consider better naming):
interface IJobIdAble
{
string HangfireJobId { get; }
}
Then you can create and add the filter (from my project):
public class IJobIdAbleFilter : IJobActivatorFilter
{
/// <summary>
/// Called after the job is constructed by the current activator.
/// </summary>
/// <param name="jobType">The type of the job being created.</param>
/// <param name="activatedJob">The object created by the activator. Should be of type found within jobType.</param>
/// <param name="context"></param>
void OnMaterialized(Type jobType, object activatedJob, [CanBeNull] JobActivatorContext context)
{
var idAble = activatedJob as IJobIdAble;
if (idAble != null)
{
idAble.HangfireJobId = context.BackgroundJob.Id
}
}
// ... override other things...
}
Than you can access the needed information via:
public void SendEmail(string name, PerformContext context)
{
string jobId = HangfireJobId;
}
Adding PerformContext
to the job method is simple and works as expected. Thanks @pieceofsummer
Can you tell me how to get Job Id of my simple function
BackgroundJob.Enqueue(() => TextBuffer.Extract(“Extraction Completed”));
The above function is just to display the string i need to get the job id of that specific
It worked thanks but now it is deprecated and from version 2.0.0 onwards this will be removed, so you can use
> public void SendEmail(string name, PerformContext context)
{ string jobId = context.BackgroundJob.Id; }