笔者的九篇反射系统文章已经完结,但是笔者会持续更新反射在日常撸码中的应用。

本篇内容主要是 .NET Core 获取运行环境信息、利用反射更加方便地处理数据。

本篇内容有:RuntimeInformation、Environment、反射、特性等。

本篇代码下载地址 https://gitee.com/whuanle/reflection_and_properties/blob/master/反射特性应用场景1.cs

获取示例:

笔者的九篇反射系列文章阅读地址如下:

C# 反射与特性(一):反射基础

C# 反射与特性(二):探究反射

C# 反射与特性(三):反射类型的成员

C# 反射与特性(四):实例化类型

C# 反射与特性(五):类型成员操作

C# 反射与特性(六):实现 ASP.NET Core 依赖注入 Web

C# 反射与特性(七):自定义特性以及应用

C# 反射与特性(八):反射操作实例大全

C# 反射与特性(九):解析反射实例大全

RuntimeInformation、Environment

RuntimeInformation 类提供有关 .NET 运行时安装的信息。主要获取平台以及 版本,API较少。

文档地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.runtimeinformation?view=netcore-3.1

Environment 提供有关当前环境和平台的信息以及操作它们的方法。API比较多。

文档地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.environment?view=netcore-3.1

以上两个类已经提供了文档地址,这里不再赘述。

需要注意的是,Windows、Linux 之间有差异,因此有些 API 是无法跨平台的。另外 .NET Core 相对 .NET Framework ,对获取系统资源信息等的 API 十分少。

.NET Core 是无有 API 获取系统 CPU 情况和 内存使用情况,倒是可以获取当前进程的 CPU 和 内存使用情况。

可以查看 stackoverflow 了解。

https://stackoverflow.com/questions/54215334/how-to-measure-cpu-usage-and-memory-for-a-process-in-net-core-linux

获取信息

下面获取的属于进程使用的内存已经使用 CPU 时间。

CPU 时间不像直接获取到的 使用百分比,可以很直观地看到。

CPU 时间地公式如下。

CPU时间 = 执行程序所需的时钟周期数 * 时钟周期时间

CPU 有多核多线程,因此不能按照运行多长时间去计算。同时进程存在休眠、上下文切换等情况。

程序运行了几小时,有可能CPU时间只有几十分钟。

对 CPU 性能计算方法有兴趣,请参考 https://www.cnblogs.com/whuanle/p/12260224.html

对 Linux CPU 使用率计算有兴趣,请查看 https://www.cnblogs.com/aresxin/p/9152127.html

我们在 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 特性,专业用来显示信息项的。这样设置,可以为属性灵活设置别名,便于显示信息以及说明。

笔者会继续带来更多反射的使用实例,融入到日常需求中。

.NET Core 获取程序运行环境信息与反射的应用的更多相关文章

  1. C# 获取程序运行时路径

    Ø  前言 开发中,很多时候都需要获取程序运行时路径,比如:反射.文件操作等..NET Framework 已经封装了这些功能,可以很方便的使用. C# 中有很多类都可以获取程序运行时路径,我们没必要 ...

  2. golang获取程序运行路径

    golang获取程序运行路径: /* 获取程序运行路径 */ func getCurrentDirectory() string { dir, err := filepath.Abs(filepath ...

  3. Python获取程序运行目录和脚本目录

    Python获取程序运行目录和脚本目录 import os import sys #获取脚本所在目录 print os.path.split( os.path.realpath( sys.argv[0 ...

  4. .NET Core 获取主机运行资源的库

    简介 CZGL.SystemInfo 是一个支持 Windows 和 Linux 的资源信息获取库,用于获取系统环境.机器资源信息.系统资源使用情况. Nuget 搜索 CZGL.SystemInfo ...

  5. [转] C# 获取程序运行目录

    来自 莫等闲也,原文 // 获取程序的基目录.  System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnosti ...

  6. Qt使用windows API获取程序运行时占用内存 good

    使用的是psapi.h中的GetProcessMemoryInfo函数,但是运行到该函数时就强制退出了. 后来,百度到原因是 原来Qt编译时加了-mthread,createprocess时要使的Ha ...

  7. unicode string和ansi string的转换函数及获取程序运行路径的代码

    #pragma once#include <string> namespace stds { class tool { public: std::string ws2s(const std ...

  8. iOS获取程序运行平台

    下面这个博客里面写的很清楚 http://blog.sina.com.cn/s/blog_890a737301014fim.html

  9. C# 获取程序运行目录

    string a = "BaseDirectory:" + AppDomain.CurrentDomain.BaseDirectory + "\r\n" + & ...

随机推荐

  1. mybatis: Invalid bound statement (not found)即使调试源码也很难注意的坑

    需要改成 注意: 这个是不能一次性建立多级目录的 这个才是ok的

  2. Perl: print @globbing."\n"; 和 print @globbing; 不一样,一个已经转换为数组元素个数了

    48 print @globbing."\n"; 输出: 3

  3. Linux_打包文件

    将多个文件打包成一个大文件,用tar命令 tar是将多个文件前后连接在一起,tar并不对文件进行压缩 tar -cf  要创建的打包文件名(最后加上.tar)  要打包的文件/列表      c代表创 ...

  4. HBase单机安装及Phoenix JDBC连接

    HBase是建立在Hadoop文件系统之上的分布式面向列的数据库,它是横向扩展的.它利用了Hadoop的文件系统(HDFS)提供的容错能力. HBase提供对数据的随机实时读/写访问,可以直接HBas ...

  5. linux上部署jenkins

    http://www.pianshen.com/article/1133171043/相关jenkins链接 下载jenkins的war包:https://blog.csdn.net/Aaron_Zh ...

  6. Yii框架的学习指南(策码秀才篇)1-2 一步步学习yii framework

    我也是新手,不过之前学习了tp和ci框架,所以尝鲜想看看yii到底有多强大. 如何新建一个webapp(网站应用)呢,下面是2个步骤: 1. cmd 切换到htdocs下面的yii目录下的framew ...

  7. python使用geopandas和shapely处理shp文件

    一.环境搭建 所需库:geopandas (以及前置库)  doc:http://geopandas.org/ shapely(以及前置库)  doc: 二.数据预处理 1.将shp文件进行切片 2. ...

  8. 羽翼sqlmap视频笔记

    access 注入 ./sqlmap.py -u "url"          注入判断./sqlmap.py -u "url" --tables  跑表./s ...

  9. cs231n spring 2017 lecture8 Deep Learning Networks

    1. CPU vs. GPU: CPU核心少(几个),更擅长串行任务.GPU有很多核心(几千个),每一个核都弱,有自己的内存(几个G),很适合并行任务.GPU最典型的应用是矩阵运算. GPU编程:1) ...

  10. Serializable中的serialVersionUID是必须的吗

    不写serialVersionUID就没有吗 即使不写, jdk反序列化时也会自动检查这个id, 反编译.class文件你也看不到这个值 rpc反序列化 如果使用jdk的方式, 这个必须配置 如果使用 ...