Hi,
I’ve just started with Hangfire and I’m planning to use it for a bunch of things, but to start with I want to create a job that will run every day at a set time, and do some database maintenance. I am using .NET Core 2.0.
I’ve got this block in my ConfigureServices method in my Startup class:
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(_configuration.GetConnectionString("ExtranetConnection"), new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
}));
services.AddHangfireServer();
And I’ve got this in my Configure method in the Startup class:
app.UseHangfireDashboard();
app.UseHangfireServer();
// Add MVC to the request execution pipeline.
app.UseMvc();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "api-docs";
c.InjectStylesheet("/swagger-ui/custom.css");
c.SwaggerEndpoint("/swagger/v1/swagger.json", $"{_configuration["application.name"]} v1");
});
//RecurringJob.RemoveIfExists(nameof(DeleteExpiredUsersJob));
RecurringJob.AddOrUpdate(nameof(DeleteExpiredUsersJob), ()=> DeleteExpiredUsersJob(userManager), Cron.Daily(14,55));
I have a further method called DeleteExpiredUsersJob which looks like this:
public void DeleteExpiredUsersJob(UserManager userManager)
{
var usersToDelete =
userManager.Users.Where(x => x.LastLogin == null || x.LastLogin < (DateTime.Now - TimeSpan.FromDays(int.Parse(_configuration.GetSection("DeleteOldUsersJob")["InactiveDays"]))));
foreach (var user in usersToDelete)
{
var result = userManager.DeleteAsync(user).Result;
//if (result.Succeeded)
//{
// logger.LogInformation($"Deleted user [{user.Id}]");
//}
//else
//{
// logger.LogWarning($"Failed to delete user [{user.Id}]");
//}
}
}
When I start the application, I get an ArgumentNullException on the line starting with RecurringJob. This is the stack trace:
System.ArgumentNullException: Value cannot be null.
Parameter name: factory
at Microsoft.Extensions.Logging.Logger`1..ctor(ILoggerFactory factory)
at lambda_method(Closure , Object[] )
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolvePropertyAndCreatorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 creator, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Hangfire.Common.SerializationHelper.Deserialize(String value, Type type, SerializationOption option)
at Hangfire.Storage.InvocationData.DeserializeArgument(String argument, Type type)
--- End of stack trace from previous location where exception was thrown ---
at Hangfire.Storage.InvocationData.DeserializeArgument(String argument, Type type)
at Hangfire.Storage.InvocationData.DeserializeArguments(MethodInfo methodInfo, String[] arguments)
at Hangfire.Storage.InvocationData.DeserializeJob()
From what I can see, the configuration is about as generic as it could possibly be. I can’t see what I’m doing wrong. It evidently relates to logging somehow, but I haven’t a clue why. I commented out any reference to logging in my method and removed the parameter for it, but I still get the same result. Am I missing a step somewhere?
Thanks
Adam