Good morning, I am creating a WinService in C# 4.6.2 and I am using Quartz.Net in version 3.7 to set up batch processing on a server. However, when I start the service I get the following error:
Service backup sage - Erreur survenue à '10:25:35' : ThreadPool type 'Quartz.Simpl.DefaultThreadPool' props could not be configured. - StackTrace : à Quartz.Impl.StdSchedulerFactory.<Instantiate>d__65.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
à Quartz.Impl.StdSchedulerFactory.<GetScheduler>d__71.MoveNext()
--- Fin de la trace de la pile à partir de l'emplacement précédent au niveau duquel l'exception a été levée ---
à System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
à SupportGriffi.WindowsService.BackupSage.ServiceBackupSage.<OnStart>d__4.MoveNext()
I followed the site documentation and used information from this site: https://mjc.si/2019/08/25/use-quartz-net-library-for-running-tasks-in-a-windows-service/
Here is my code:
Service :
public ServiceBackupSage()
{
InitializeComponent();
m_ServiceLog = new EventLog();
string sourceNameService = Properties.Settings.Default.SourceName;
string logNameService = Properties.Settings.Default.LogName;
if (!System.Diagnostics.EventLog.SourceExists(sourceNameService))
{
System.Diagnostics.EventLog.CreateEventSource(sourceNameService, logNameService);
}
// configure the event log instance to use this source name
m_ServiceLog.Source = sourceNameService;
m_ServiceLog.Log = logNameService;
}
protected override async void OnStart(string[] args)
{
try
{
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "Le service backup sage s'est lancé à {0}.", DateTime.Now), EventLogEntryType.Information);
var properties = new NameValueCollection();
properties.Add("quartz.scheduler.instanceName", "SchedulerSage");
properties.Add("quartz.threadPool.type", "Quartz.Simpl.SimpleThreadPool, Quartz");
properties.Add("quartz.threadPool.threadCount", "0");
//properties.Add("quartz.threadPool.threadPriority", "Normal");
properties.Add("quartz.threadPool.maxConcurrency", "1");
m_SchedulerFactory = new StdSchedulerFactory(properties);
// get a scheduler
m_Scheduler = await m_SchedulerFactory.GetScheduler();
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "m_SchedulerFactory.GetScheduler OK {0}.", DateTime.Now), EventLogEntryType.Information);
await m_Scheduler.Start();
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "Start Scheduler OK {0}.", DateTime.Now), EventLogEntryType.Information);
//// define the job and tie it to our UserSyncJob class using configurations from app.config as a job data.
var job = JobBuilder.Create<BackupSageJob>()
.WithIdentity("BackupSageJob", "DefaultGroup")
.UsingJobData("IPServer", Properties.Settings.Default.IPServeur)
.UsingJobData("Login", Properties.Settings.Default.Login)
.UsingJobData("Port", Properties.Settings.Default.Port)
.UsingJobData("Password", Properties.Settings.Default.Password)
.Build();
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "Création du Job Quartz OK {0}.", DateTime.Now), EventLogEntryType.Information);
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("BackupSageTrigger", "DefaultGroup")
.StartNow()
.WithCronSchedule(Properties.Settings.Default.CronSchedule)
.Build();
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "Création du trigger Quartz OK {0}.", DateTime.Now), EventLogEntryType.Information);
// Tell Quartz to schedule the job using our trigger
await m_Scheduler.ScheduleJob(job, trigger);
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "Schedule Job lancé {0}.", DateTime.Now), EventLogEntryType.Information);
// some sleep to show what's happening
await Task.Delay(TimeSpan.FromSeconds(5));
}
catch (Exception ex)
{
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture, "Service backup sage - Erreur survenue à '{0}' : {1} - StackTrace : {2}",
DateTime.Now.ToString("HH:mm:ss"),
ex.Message.ToString(),
ex.StackTrace.ToString()), EventLogEntryType.Error);
throw ex;
}
}
protected override async void OnStop()
{
try
{
await m_Scheduler.Shutdown();
// Log d'arrêt du service
m_ServiceLog.WriteEntry(string.Format(CultureInfo.CurrentCulture,
"Le service backup sage s'est arreté à '{0}'.",
DateTime.Now.ToString("HH:mm:ss")), EventLogEntryType.Information);
// Fermeture du journal d'évènement
m_ServiceLog.Close();
}
catch (Exception ex)
{
throw ex;
}
Class IJob :
public class BackupSageJob : IJob
{
#region Membres
/// <summary>
/// Indique si le traitement est en cours
/// </summary>
private static bool m_IsRunning;
/// <summary>
/// Journal d'évènement du service
/// </summary>
private EventLog m_ServiceLog;
#endregion Membres
public BackupSageJob()
{
string sourceNameService = Properties.Settings.Default.SourceName;
string logNameService = Properties.Settings.Default.LogName;
// Instanciation du journal d'évènement
m_ServiceLog = new EventLog(logNameService);
m_ServiceLog.Source = sourceNameService;
}
public Task Execute(IJobExecutionContext context)
{
try
{
// Log de démarrage
m_ServiceLog.WriteEntry(string.Format(CultureInfo.InvariantCulture, "Lancement de la tache du backup des bases Sage {0}:{1}", DateTime.Now.Hour.ToString("00"),
DateTime.Now.Minute.ToString("00")),
EventLogEntryType.Information);
//Load Job configuration
var key = context.JobDetail.Key;
var dataMap = context.JobDetail.JobDataMap;
var ipftp = dataMap.GetString("IPServer");
var login = dataMap.GetString("Login");
var port = dataMap.GetString("Port");
var password = dataMap.GetString("Password");
Task taskBackup = new Task(() => BackupSageService.LaunchBackup(ipftp, login, password));
taskBackup.Start();
// Log de succès
m_ServiceLog.WriteEntry(string.Format(CultureInfo.InvariantCulture,
"Fin de la tache de la tache du backup des bases Sage {0}:{1}",
DateTime.Now.Hour.ToString("00"), DateTime.Now.Minute.ToString("00")),
EventLogEntryType.Information);
return taskBackup;
}
catch (Exception e)
{
m_ServiceLog.WriteEntry(string.Format(CultureInfo.InvariantCulture,
"Erreur de la tache de la tache du backup des bases Sage {0}:{1}\n{2}",
DateTime.Now.Hour.ToString("00"),
DateTime.Now.Minute.ToString("00"),
EventLogEntryType.Error,
e.Message));
return Task.CompletedTask;
}
}
}
I don't know what to add in the properties to make this Windows Service work. Do you have any ideas ?
I thank you in advance
I tried to modify the properties using the answer from this site: https://github.com/quartznet/quartznet/issues/436
and it doesn't work.
By searching the Quartz.Net code I found the place that throws the exception
in class : class StdSchedulerFactory : ISchedulerFactory
the method : private async Task Instantiate()
in class: ObjectUtils the method :
And I keep looking... it's really not easy!