案例:修改預設線程個數 1.NameValueCollection System.Collections.Specialized.NameValueCollection collection = new System.Collections.Specialized.NameValueCollecti ...
案例:修改預設線程個數
1.NameValueCollection
System.Collections.Specialized.NameValueCollection collection = new System.Collections.Specialized.NameValueCollection(); collection.Add("quartz.threadPool.ThreadCount","20"); var factory= new StdSchedulerFactory(collection); var scheduler= await factory.GetScheduler(); await scheduler.Start(); var metData=await scheduler.GetMetaData(); Console.WriteLine(metData.ThreadPoolSize);
原理
通過反射實例化對象DefaultThreadPool
Type tpType = loadHelper.LoadType(threadPoolTypeString) ?? typeof(DefaultThreadPool); try { tp = ObjectUtils.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; }
設置對象的屬性
public static void SetObjectProperties(object obj, NameValueCollection props) { // remove the type props.Remove("type"); foreach (string name in props.Keys) { string propertyName = CultureInfo.InvariantCulture.TextInfo.ToUpper(name.Substring(0, 1)) + name.Substring(1); try { object value = props[name]; SetPropertyValue(obj, propertyName, value); } catch (Exception nfe) { throw new SchedulerConfigException( $"Could not parse property '{name}' into correct data type: {nfe.Message}", nfe); } } }
通過反射設置屬性的值
public static void SetPropertyValue(object target, string propertyName, object value) { Type t = target.GetType(); PropertyInfo pi = t.GetProperty(propertyName); if (pi == null || !pi.CanWrite) { // try to find from interfaces foreach (var interfaceType in target.GetType().GetInterfaces()) { pi = interfaceType.GetProperty(propertyName); if (pi != null && pi.CanWrite) { // found suitable break; } } } if (pi == null) { // not match from anywhere throw new MemberAccessException($"No writable property '{propertyName}' found"); } MethodInfo mi = pi.GetSetMethod(); if (mi == null) { throw new MemberAccessException($"Property '{propertyName}' has no setter"); } if (mi.GetParameters()[0].ParameterType == typeof(TimeSpan)) { // special handling value = GetTimeSpanValueForProperty(pi, value); } else { value = ConvertValueIfNecessary(mi.GetParameters()[0].ParameterType, value); } mi.Invoke(target, new[] {value}); }
結果圖
2.App.config(只在.NETFramework生效)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </configSections> <quartz> <add key="quartz.threadPool.ThreadCount" value="11"/> </quartz> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> </configuration>
static void Main(string[] args) { var scheduler =new StdSchedulerFactory().GetScheduler().Result; scheduler.Start(); var metaData=scheduler.GetMetaData().Result; Console.WriteLine(metaData.ThreadPoolSize); Console.Read(); }
結果圖
原理
通過ConfigurationManager.GetSection()來獲取App.config裡面的值,如果有就轉換成NameValueCollection
public virtual void Initialize() { // short-circuit if already initialized if (cfg != null) { return; } if (initException != null) { throw initException; } var props = Util.Configuration.GetSection(ConfigurationSectionName); }
internal static NameValueCollection GetSection(string sectionName) { try { return (NameValueCollection) ConfigurationManager.GetSection(sectionName); } catch (Exception e) { log.Warn("could not read configuration using ConfigurationManager.GetSection: " + e.Message); return null; } }
3.quartz.config
quartz.threadPool.ThreadCount=20
System.Collections.Specialized.NameValueCollection collection = new System.Collections.Specialized.NameValueCollection(); //collection.Add("quartz.threadPool.ThreadCount","20"); //var factory= new StdSchedulerFactory(collection); var factory = new StdSchedulerFactory(); var scheduler= await factory.GetScheduler(); await scheduler.Start(); var metData=await scheduler.GetMetaData(); Console.WriteLine(metData.ThreadPoolSize);
結果圖
原理
判斷當前程式中是否有quartz.config這個文件
如果有則讀取
if (props == null && File.Exists(propFileName)) { // file system try { PropertiesParser pp = PropertiesParser.ReadFromFileResource(propFileName); props = pp.UnderlyingProperties; Log.Info($"Quartz.NET properties loaded from configuration file '{propFileName}'"); } catch (Exception ex) { Log.ErrorException("Could not load properties for Quartz from file {0}: {1}".FormatInvariant(propFileName, ex.Message), ex); } }
#表示註釋
!END代表結束,如果沒有就讀取全部
public static PropertiesParser ReadFromFileResource(string fileName) { return ReadFromStream(File.OpenRead(fileName)); } private static PropertiesParser ReadFromStream(Stream stream) { NameValueCollection props = new NameValueCollection(); using (StreamReader sr = new StreamReader(stream)) { string line; while ((line = sr.ReadLine()) != null) { line = line.TrimStart(); if (line.StartsWith("#")) { // comment line continue; } if (line.StartsWith("!END")) { // special end condition break; } string[] lineItems = line.Split(new[] { '=' }, 2); if (lineItems.Length == 2) { props[lineItems[0].Trim()] = lineItems[1].Trim(); } } } return new PropertiesParser(props); }
4.Environment(環境變數)
Environment.SetEnvironmentVariable("quartz.threadPool.ThreadCount","50"); System.Collections.Specialized.NameValueCollection collection = new System.Collections.Specialized.NameValueCollection(); //collection.Add("quartz.threadPool.ThreadCount","20"); //var factory= new StdSchedulerFactory(collection); var factory = new StdSchedulerFactory(); var scheduler= await factory.GetScheduler(); await scheduler.Start(); var metData=await scheduler.GetMetaData(); Console.WriteLine(metData.ThreadPoolSize);
結果圖
原理
public virtual void Initialize() { 。。。。。。 Initialize(OverrideWithSysProps(props)); }
獲取所有的環境變數,然後賦值給NameValueCollection
private static NameValueCollection OverrideWithSysProps(NameValueCollection props) { NameValueCollection retValue = new NameValueCollection(props); IDictionary<string, string> vars = QuartzEnvironment.GetEnvironmentVariables(); foreach (string key in vars.Keys) { retValue.Set(key, vars[key]); } return retValue; }
quartz.config<app.config<環境變數<NameValueCollection