question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Quartz tries to access disposed logger after the host has been restarted

See original GitHub issue

Describe the bug

For architectural reasons of my aspnetcore project, the host building and execution is in a for loop, since you can restart the server from the client, something like this


async Task LoadAsync()
{
	var builder = WebApplication.CreateBuilder(args);
        // Configuration
        builder.Services.AddQuartz(b =>
	{
		b.SchedulerId = "1";
		b.SchedulerName = "EAE";
		b.UseMicrosoftDependencyInjectionJobFactory();
	});

	builder.Services.AddQuartzServer(options =>
	{
		options.WaitForJobsToComplete = true;
	});

        var app = builder.Build();
        // Configuration
        app.Run();
}

while (true)
{
	await LoadAsync();
}

The first run, there are no problems. But when I force the WebApplicationHost to stop using IHostApplicationLifetime.StopApplication(), while everything restarts correctly, Quartz crashes with this error

Unhandled exception. System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'LoggerFactory'.
   at Microsoft.Extensions.Logging.LoggerFactory.CreateLogger(String categoryName)
   at Quartz.Simpl.MicrosoftLoggingProvider.GetLogger(String name)
   at Quartz.Logging.LogProvider.GetLogger(String name)
   at Quartz.Xml.XMLSchedulingDataProcessor..ctor(ITypeLoadHelper typeLoadHelper)
   at Quartz.ContainerConfigurationProcessor..ctor(ITypeLoadHelper typeLoadHelper, IOptions`1 options)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Microsoft.AspNetCore.Builder.WebApplication.Run(String url)

It seems like Quartz caches globally the injected Microsoft Logger, so when the host is stopped and the logger is disposed, the same reference remains

Version used 3.5.0

To Reproduce

A code like the one I showed before with some event that calls IHostApplicationLifetime.StopApplication()

Expected behavior

It should not raise that error

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:15 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
manuelelucchicommented, Oct 11, 2022

I’ll dig it up and let you know if I’m able to

0reactions
joolifycommented, Apr 24, 2023

This issue disappeared when I changed to CreateDefaultBuilder and UseWindowsService from CreateBuilder of WebApplication.

var builder = Host.CreateDefaultBuilder(args).UseWindowsService();

builder.Services.AddQuartz(b =>
{
	b.SchedulerId = "1";
	b.SchedulerName = "EAE";
	b.UseMicrosoftDependencyInjectionJobFactory();
});

builder.Services.AddQuartzServer(options =>
{
	options.WaitForJobsToComplete = true;
});

var app = builder.Build();
// Configuration
app.Run();
Read more comments on GitHub >

github_iconTop Results From Across the Web

package seems to break functional testing with a Microsoft. ...
I'm using Quartz like this in my code and everything works as ... problem i.e. ObjectDisposedException when trying to access logger factory.
Read more >
c# Quartz.NET injected IServiceProvider is always disposed
I have an application in .NET 7 that is supposed to use Quartz to run scheduled jobs. The problem is that if I...
Read more >
Using Quartz.NET with ASP.NET Core and worker services
In this post I show how to run Quartz.NET jobs in ASP.NET Core and worker service apps using the Quartz.Extensions.Hosting package.
Read more >
quartznet
Quartz Enterprise Scheduler .NET.
Read more >
Creating a Quartz.NET hosted service with ASP.NET Core
In this post I describe how to run Quartz.NET jobs using an ASP.NET Core hosted service, and how to handle scoped services inside...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found