I have set up Hangfire with Autofac within ASP.NET Web API application.
The exception "The type does not contain a method with signature SendFromQueue(Int32)" happens when Hangfire tries to enqueue a job. The job is successfully scheduled and uses ID to a content stored in database (so I only pass the ID parameter to the service method call).
This is what my scheduled job looks like in Hangfire dashboard:
using MyServices;
MailerService mailerService = Activate<MailerService>();
mailerService.SendFromQueue(2);
The exception:
Failed Can not change the state of a job to ‘Enqueued’: target method was not found.
System.InvalidOperationException
The type MyServices.MailerService does not contain a method with signature SendFromQueue(Int32)
System.InvalidOperationException: The type MyServices.MailerService does not contain a method with signature SendFromQueue(Int32)
at HangFire.Storage.InvocationData.Deserialize()
How I schedule:
// add to HangFire schedule
BackgroundJob.Schedule<MailerService>(ms => ms.SendFromQueue(queued.Id), TimeSpan.FromMinutes(2));
O_o this is very interesting… This exception occurs because the type.GetMethod(Method, parameterTypes); returns null value. We can achieve this result when:
The type variable points to different type. Do you have another MailerService type loaded in your application domain?
Method and parameterTypes values are wrong, however we can see that they are correct.
Target method visibility is not public, but we can see it is public from the code snippet above.
Target method is declared in one of base classes, but you denied it (by the way, this is a wrong behavior).
Do you know other ways to receive the null result after calling the GetMethod method?
this still remains an unresolved issue. Is it possible that somehow the activator does not create a service instance when trying to run the scheduled job? And subsequently doesn’t find the requested method?
My add to queue code works (the MailerService is registered within AutoFac and AutoFac does resolve it at runtime when inside my code):
// add to mail queue (this works)
var queued = await MailerService.AddToQueue(mailMsgDto);
// add to HangFire schedule
BackgroundJob.Schedule<MailerService>(ms => ms.SendFromQueue(queued.Id), TimeSpan.FromMinutes(2));
How does Aufofac activator actually create service instances for background jobs?
I added Hangfire.Core project to my solution to be able to debug it and the InvocationData.Deserialize() always managed to find the method when in Debug session. Job still failed couple of times then after few more retries it just succeeded one time. However, emails still weren’t sent.
whoa, after debugging this I finally got it resolved. The problem actually was in the SendFromQueue() method which was failing to deserialize our MailMessageDto which we serialized in the AddToQueue() step. The issue was with the System.Net.MailAddress class. This didn’t show up until I debugged deep down into my code.
Seems that anytime something goes wrong within our jobs the above exception occurs. I just ran into some issues with async which resulted in Thread being aborted exception within my jobs (yes, I know async is not yet supported, just read about that) and that same exception was being thrown within Hangfire.
Is there a way that exception details would somehow be propagated into the Dashboard?
Please check if you have multiple Hangfire servers registered (running) with different codebases. In my case, it was our production server and my own development server. I was testing on my own development machine with newer code but the scheduled Jobs somehow ended to be run by the production server (which had old code, lacking some crucial methods etc.) thus resulting in this exception.