IT教程 ·

.NET Core 猎取程序运转环境信息与反射的运用

一起了解 .Net Foundation 项目 No.8

笔者的九篇反射体系文章已结束,然则笔者会延续更新反射在一样平常撸码中的运用。
本篇内容主假如 .NET Core 猎取运转环境信息、应用反射越发轻易地处置惩罚数据。
本篇内容有:RuntimeInformation、Environment、反射、特征等。
本篇代码下载地点

猎取示例:
.NET Core 猎取程序运转环境信息与反射的运用 IT教程 第1张

笔者的九篇反射系列文章浏览地点以下:

RuntimeInformation、Environment

RuntimeInformation 类供应有关 .NET 运转时装置的信息。重要猎取平台以及 版本,API较少。
文档地点
Environment 供应有关当前环境和平台的信息以及操纵它们的要领。API比较多。
文档地点

以上两个类已供应了文档地点,这里不再赘述。
须要注重的是,Windows、Linux 之间有差别,因而有些 API 是没法跨平台的。别的 .NET Core 相对 .NET Framework ,对猎取体系资本信息等的 API 非常少。
.NET Core 是无有 API 猎取体系 CPU 状况和 内存运用状况,却是能够猎取当前历程的 CPU 和 内存运用状况。
能够检察 stackoverflow 相识。

猎取信息

下面猎取的属于历程运用的内存已运用 CPU 时候。
CPU 时候不像直接猎取到的 运用百分比,能够很直观地看到。
CPU 时候地公式以下。
CPU时候 = 实行程序所需的时钟周期数 * 时钟周期时候
CPU 有多核多线程,因而不能根据运转多长时候去盘算。同时历程存在休眠、上下文切换等状况。
程序运转了几小时,有大概CPU时候只要几非常钟。
对 CPU 机能盘算要领有兴致,请参考
对 Linux CPU 运用率盘算有兴致,请检察

我们在 C# 中运用地代码以下

    [Display(Name = "运转信息")]
    public class ApplicationRunInfo
    {
        private double _UsedMem;
        private double _UsedCPUTime;
        public ApplicationRunInfo()
        {
            var proc = Process.GetCurrentProcess();
            var mem = proc.WorkingSet64;
            var cpu = proc.TotalProcessorTime;
            _UsedMem = mem / 1024.0;
            _UsedCPUTime = cpu.TotalMilliseconds;
        }
        [Display(Name = "历程已运用物理内存(kb)")]
        public double UsedMem { get { return _UsedMem; } }
        [Display(Name = "历程已占耗CPU时候(ms)")]
        public double UsedCPUTime { get { return _UsedCPUTime; } }
    }

这里只要两个属性。
我们运用 Display 特征来标记此属性地的寄义,轻易反射时猎取信息。

别的另有两个猎取差别范例信息的类以下


    [Display(Name = "体系运转平台")]
    public class SystemPlatformInfo
    {
        [Display(Name = "运转框架")]
        public string FrameworkDescription { get { return RuntimeInformation.FrameworkDescription; } }
        [Display(Name = "操纵体系")]
        public string OSDescription { get { return RuntimeInformation.OSDescription; } }
        [Display(Name = "操纵体系版本")]
        public string OSVersion { get { return Environment.OSVersion.ToString(); } }
        [Display(Name = "平台架构")]
        public string OSArchitecture { get { return RuntimeInformation.OSArchitecture.ToString(); } }
    }

    [Display(Name = "运转环境")]
    public class SystemRunEvnInfo
    {
        [Display(Name = "机械称号")]
        public string MachineName { get { return Environment.MachineName; } }
        [Display(Name = "用户收集域名")]
        public string UserDomainName { get { return Environment.UserDomainName; } }
        [Display(Name = "分区磁盘")]
        public string GetLogicalDrives { get { return string.Join(", ", Environment.GetLogicalDrives()); } }
        [Display(Name = "体系目次")]
        public string SystemDirectory { get { return Environment.SystemDirectory; } }
        [Display(Name = "体系已运转时候(毫秒)")]
        public int TickCount { get { return Environment.TickCount; } }

        [Display(Name = "是不是在交互形式中运转")]
        public bool UserInteractive { get { return Environment.UserInteractive; } }
        [Display(Name = "当前关联用户名")]
        public string UserName { get { return Environment.UserName; } }
        [Display(Name = "Web程序中心框架版本")]
        public string Version { get { return Environment.Version.ToString(); } }

        //对Linux无效
        [Display(Name = "磁盘分区")]
        public string SystemDrive { get { return Environment.ExpandEnvironmentVariables("%SystemDrive%"); } }
        //对Linux无效
        [Display(Name = "体系目次")]
        public string SystemRoot { get { return Environment.ExpandEnvironmentVariables("%SystemRoot%"); } }
    }

大概你会认为,为何不写成要领,为啥要写得这么新鲜。不急,逐步看下去~

 

反射猎取信息

我们来定义一个静态范例,作为猎取种种信息的进口。

public static class EnvironmentInfo
{

}
}

猎取属性值

反射猎取属性值的要领,用于猎取上述几个类的属性值。

        /// <summary>
        /// 猎取属性的值
        /// </summary>
        /// <param name="info"></param>
        /// <param name="obj">实例</param>
        /// <returns></returns>
        private static object GetPropertyInfoValue(PropertyInfo info, object obj)
        {
            return info.GetValue(obj);
        }

反射猎取特征值

我们运用了特征 [Display(Name = "当前关联用户名")] 来存储别号。
我们要经由过程反射猎取 Dispaly 特征的 Name 属性值。

        /// <summary>
        /// 猎取 [Display] 特征的属性 Name 的值
        /// </summary>
        /// <param name="attrs"></param>
        /// <returns></returns>
        private static string GetDisplayNameValue(IList<CustomAttributeData> attrs)
        {
            var argument = attrs.FirstOrDefault(x => x.AttributeType.Name == nameof(DisplayAttribute)).NamedArguments;
            return argument.FirstOrDefault(x => x.MemberName == nameof(DisplayAttribute.Name)).TypedValue.Value.ToString();
        }

猎取某个属性的值以及别号

我们运用了如许的体式格局去设置猎取一项信息

        [Display(Name = "操纵体系")]
        public string OSDescription { get { return RuntimeInformation.OSDescription; } }

因而我们要猎取到一个范例一切的属性值和属性的特征值。

        /// <summary>
        /// 猎取某个范例的值以及称号
        /// </summary>
        /// <typeparam name="TInfo"></typeparam>
        /// <param name="info"></param>
        /// <returns></returns>
        private static (string, List<KeyValuePair<string, object>>) GetValues<TInfo>(TInfo info)
        {
            List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
            Type type = info.GetType();
            PropertyInfo[] pros = type.GetProperties();
            foreach (var item in pros)
            {
                var name = GetDisplayNameValue(item.GetCustomAttributesData());
                var value = GetPropertyInfoValue(item, info);
                list.Add(new KeyValuePair<string, object>(name, value));
            }
            return
                (GetDisplayNameValue(info.GetType().GetCustomAttributesData()),
                list);
        }

反射猎取信息

上面的东西要领定义后,我们来设置差别的要领猎取差别的信息。

        /// <summary>
        /// 猎取程序运转资本信息
        /// </summary>
        /// <returns></returns>
        public static (string, List<KeyValuePair<string, object>>) GetApplicationRunInfo()
        {
            ApplicationRunInfo info = new ApplicationRunInfo();
            return GetValues(info);
        }

        /// <summary>
        /// 猎取体系运转平台信息
        /// </summary>
        /// <returns></returns>
        public static (string, List<KeyValuePair<string, object>>) GetSystemPlatformInfo()
        {
            SystemPlatformInfo info = new SystemPlatformInfo();
            return GetValues(info);
        }

        /// <summary>
        /// 猎取体系运转环境信息
        /// </summary>
        /// <returns></returns>
        public static (string, List<KeyValuePair<string, object>>) GetSystemRunEvnInfo()
        {
            SystemRunEvnInfo info = new SystemRunEvnInfo();
            return GetValues(info);
        }

另有一个要领猎取环境变量的,不须要应用上面的范例-属性来操纵,能够直接封装到要领中。

        /// <summary>
        /// 猎取体系悉数环境变量
        /// </summary>
        /// <returns></returns>
        public static (string, List<KeyValuePair<string, object>>) GetEnvironmentVariables()
        {
            List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
            IDictionary environmentVariables = Environment.GetEnvironmentVariables();
            foreach (DictionaryEntry de in environmentVariables)
            {
                list.Add(new KeyValuePair<string, object>(de.Key.ToString(), de.Value));
            }
            return ("体系环境变量", list);
        }

运用

我们在 Program 中,这些写就能够输出一切信息了

        static void Main(string[] args)
        {
            var a = EnvironmentInfo.GetApplicationRunInfo();
            var b = EnvironmentInfo.GetSystemPlatformInfo();
            var c = EnvironmentInfo.GetSystemRunEvnInfo();
            var d = EnvironmentInfo.GetEnvironmentVariables();
            ConsoleInfo(a.Item1, a.Item2);
            ConsoleInfo(b.Item1, b.Item2);
            ConsoleInfo(c.Item1, c.Item2);
            ConsoleInfo(d.Item1, d.Item2);
            Console.ReadKey();
        }
        public static void ConsoleInfo(string title, List<KeyValuePair<string, object>> list)
        {
            Console.WriteLine("n***********" + title + "***********");
            foreach (var item in list)
            {
                Console.WriteLine(item.Key + ":" + item.Value);
            }
        }

在 Linux 中显现

总结

我以上运用了 类-属性 来作为猎取功用,如许能够没必要写许多要领去挪用猎取环境信息,属性就是数据。既轻易序列化,又轻易反射。
同时,假如先拓展信息项,直接增加上去就行,反射直接悉数拿到手。
别的有个 Display 特征,专业用来显现信息项的。如许设置,能够为属性天真设置别号,便于显现信息以及申明。

笔者会继承带来更多反射的运用实例,融入到一样平常需求中。

Nginx之负载节点状态监测

参与评论