提问人:NicolasGrif 提问时间:11/14/2023 更新时间:11/14/2023 访问量:21
Winservice C# 和 Quartz.net v3.7 - 错误“无法配置 ThreadPool 类型'Quartz.Simpl.DefaultThreadPool' props”
Winservice C# and Quartz.net v3.7 - Error "ThreadPool type 'Quartz.Simpl.DefaultThreadPool' props could not be configured"
问:
早上好 我正在 C# 4.6.2 中创建 WinService,并在 3.7 版中使用 Quartz.Net 在服务器上设置批处理。 但是,当我启动服务时,出现以下错误:
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()
我遵循了网站文档并使用了来自此网站的信息:https://mjc.si/2019/08/25/use-quartz-net-library-for-running-tasks-in-a-windows-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;
}
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;
}
}
}
我不知道在属性中添加什么才能使此 Windows 服务正常工作。 你有什么想法吗?
我提前谢谢你
我尝试使用这个网站的答案修改属性:https://github.com/quartznet/quartznet/issues/436
它不起作用。
答:
0赞
NicolasGrif
11/14/2023
#1
通过搜索 Quartz.Net 代码,我找到了抛出异常的地方
在类中:类 StdSchedulerFactory:ISchedulerFactory
方法:私有异步任务 Instantiate()
// Get ThreadPool Properties
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var threadPoolTypeString = cfg.GetStringProperty(PropertyThreadPoolType).NullSafeTrim();
if (threadPoolTypeString != null
&& threadPoolTypeString.StartsWith("Quartz.Simpl.SimpleThreadPool", StringComparison.OrdinalIgnoreCase))
{
// default to use as synonym for now
threadPoolTypeString = typeof(DefaultThreadPool).AssemblyQualifiedNameWithoutVersion();
}
Type tpType = loadHelper.LoadType(threadPoolTypeString) ?? typeof(DefaultThreadPool);
try
{
tp = InstantiateType<IThreadPool>(tpType);
}
catch (Exception e)
{
initException = new SchedulerException("ThreadPool type '{0}' could not be instantiated.".FormatInvariant(tpType), e);
throw initException;
}
tProps = cfg.GetPropertyGroup(PropertyThreadPoolPrefix, true);
try
{
ObjectUtils.SetObjectProperties(tp, tProps);
}
catch (Exception e)
{
**initException = new SchedulerException("ThreadPool type '{0}' props could not be configured.".FormatInvariant(tpType), e);
throw initException;**
}
在类中: ObjectUtils 方法:
/// <summary>
/// Sets the object properties using reflection.
/// </summary>
/// <param name="obj">The object to set values to.</param>
/// <param name="props">The properties to set to object.</param>
public static void SetObjectProperties(object obj, NameValueCollection props)
{
// remove the type
props.Remove("type");
foreach (string name in props.Keys)
{
try
{
var value = props[name];
SetPropertyValue(obj, name, value);
}
catch (Exception nfe)
{
throw new SchedulerConfigException(
$"Could not parse property '{name}' into correct data type: {nfe.Message}", nfe);
}
}
}
我一直在寻找......这真的不容易!
评论