1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Management; using System.Runtime.InteropServices; using System.Text; namespace ConsoleApp1 { /// /// 系统信息类 - 获取CPU、内存、磁盘、进程信息 /// public class SystemInfo { private int m_ProcessorCount = 0; //CPU个数 private PerformanceCounter pcCpuLoad; //CPU计数器 private long m_PhysicalMemory = 0; //物理内存 private const int GW_HWNDFIRST = 0; private const int GW_HWNDNEXT = 2; private const int GWL_STYLE = (-16); private const int WS_VISIBLE = 268435456; private const int WS_BORDER = 8388608; #region AIP声明 [DllImport("IpHlpApi.dll")] extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder); [DllImport("User32")] private extern static int GetWindow(int hWnd, int wCmd); [DllImport("User32")] private extern static int GetWindowLongA(int hWnd, int wIndx); [DllImport("user32.dll")] private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize); [DllImport("user32", CharSet = CharSet.Auto)] private extern static int GetWindowTextLength(IntPtr hWnd); #endregion #region 构造函数 /// /// 构造函数,初始化计数器等 /// public SystemInfo() { //初始化CPU计数器 pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total"); pcCpuLoad.MachineName = "."; pcCpuLoad.NextValue(); //CPU个数 m_ProcessorCount = Environment.ProcessorCount; //获得物理内存 ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if (mo["TotalPhysicalMemory"] != null) { m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString()); } } } #endregion #region CPU个数 /// /// 获取CPU个数 /// public int ProcessorCount { get { return m_ProcessorCount; } } #endregion #region CPU占用率 /// /// 获取CPU占用率 /// public float CpuLoad { get { return pcCpuLoad.NextValue(); } } #endregion #region 可用内存 /// /// 获取可用内存 /// public long MemoryAvailable { get { long availablebytes = 0; //ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfRawData_PerfOS_Memory"); //foreach (ManagementObject mo in mos.Get()) //{ // availablebytes = long.Parse(mo["Availablebytes"].ToString()); //} ManagementClass mos = new ManagementClass("Win32_OperatingSystem"); foreach (ManagementObject mo in mos.GetInstances()) { if (mo["FreePhysicalMemory"] != null) { availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString()); } } return availablebytes; } } #endregion #region 物理内存 /// /// 获取物理内存 /// public long PhysicalMemory { get { return m_PhysicalMemory; } } #endregion #region 获得分区信息 /// /// 获取分区信息 /// public List<DiskInfo> GetLogicalDrives() { List<DiskInfo> drives = new List<DiskInfo>(); ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk"); ManagementObjectCollection disks = diskClass.GetInstances(); foreach (ManagementObject disk in disks) { // DriveType.Fixed 为固定磁盘(硬盘) if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed) { drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString()))); } } return drives; } /// /// 获取特定分区信息 /// /// 盘符 public List<DiskInfo> GetLogicalDrives(char DriverID) { List<DiskInfo> drives = new List<DiskInfo>(); WqlObjectQuery wmiquery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceID = ’" + DriverID + ":’"); ManagementObjectSearcher wmifind = new ManagementObjectSearcher(wmiquery); foreach (ManagementObject disk in wmifind.Get()) { if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed) { drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString()))); } } return drives; } #endregion #region 获得进程列表 /// /// 获得进程列表 /// public List<ProcessInfo> GetProcessInfo() { List<ProcessInfo> pInfo = new List<ProcessInfo>(); Process[] processes = Process.GetProcesses(); foreach (Process instance in processes) { try { pInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName, instance.TotalProcessorTime.TotalMilliseconds, instance.WorkingSet64, instance.MainModule.FileName)); } catch { } } return pInfo; } /// /// 获得特定进程信息 /// /// 进程名称 public List<ProcessInfo> GetProcessInfo(string ProcessName) { List<ProcessInfo> pInfo = new List<ProcessInfo>(); Process[] processes = Process.GetProcessesByName(ProcessName); foreach (Process instance in processes) { try { pInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName, instance.TotalProcessorTime.TotalMilliseconds, instance.WorkingSet64, instance.MainModule.FileName)); } catch { } } return pInfo; } #endregion #region 结束指定进程 /// /// 结束指定进程 /// /// 进程的 Process ID public static void EndProcess(int pid) { try { Process process = Process.GetProcessById(pid); process.Kill(); } catch { } } #endregion #region 查找所有应用程序标题 /// /// 查找所有应用程序标题 /// /// 应用程序标题范型 public static List<string> FindAllApps(int Handle) { List<string> Apps = new List<string>(); int hwCurr; hwCurr = GetWindow(Handle, GW_HWNDFIRST); while (hwCurr > 0) { int IsTask = (WS_VISIBLE | WS_BORDER); int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE); bool TaskWindow = ((lngStyle & IsTask) == IsTask); if (TaskWindow) { int length = GetWindowTextLength(new IntPtr(hwCurr)); StringBuilder sb = new StringBuilder(2 * length + 1); GetWindowText(hwCurr, sb, sb.Capacity); string strTitle = sb.ToString(); if (!string.IsNullOrEmpty(strTitle)) { Apps.Add(strTitle); } } hwCurr = GetWindow(hwCurr, GW_HWNDNEXT); } return Apps; } #endregion } public class DiskInfo { public DiskInfo() { } public DiskInfo(string name, long size, long freeSpace) { this.Name = name; this.Size = size; this.FreeSpace = freeSpace; } public string Name { get; set; } public long Size { get; set; } public long FreeSpace { get; set; } } public class ProcessInfo { public ProcessInfo() { } public ProcessInfo(int id, string processName, double totalMilliseconds, long workingSet64, string fileName) { Id = id; ProcessName = processName; TotalMilliseconds = totalMilliseconds; WorkingSet64 = workingSet64; FileName = fileName; } public int Id { get; set; } public string ProcessName { get; set; } public double TotalMilliseconds { get; set; } public long WorkingSet64 { get; set; } public string FileName { get; set; } } } |
参考: https://www.cnblogs.com/zery/p/6256850.html https://www.cnblogs.com/maowang1991/archive/2013/08/27/3285983.html
View Details管理-->事件查看器 可以查看【应用程序】、【安全】、【系统】等分类的日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
static void Main(string[] args) { EventLog eventlog = new EventLog(); eventlog.Log = "Security"; //"Application"应用程序, "Security"安全, "System"系统 EventLogEntryCollection eventLogEntryCollection = eventlog.Entries; foreach (EventLogEntry entry in eventLogEntryCollection) { //if (entry.EventID == 4624) //{ // continue; //} string info = string.Empty; if (@"TaskScheduler" == entry.Source.ToString()) { info += "类型:" + entry.EntryType.ToString() + ";"; info += "日期" + entry.TimeGenerated.ToLongDateString() + ";"; info += "时间" + entry.TimeGenerated.ToLongTimeString() + ";"; info += "来源" + entry.Source.ToString() + ";"; Console.WriteLine(info); } } } |
from:https://www.cnblogs.com/gossip/p/5249982.html
View Details【Dumb slave】改成了【Permanent Agent】,效果一致 参考:http://serverfault.com/questions/793619/jenkins-trying-to-add-a-dumb-slave-but-the-option-is-missing-any-idea-how-to-a 没有【Launch agent via Java Web Start】选项: 需要开启【TCP port for JNLP agents】: 参考:http://serverfault.com/questions/794783/the-option-to-launch-slave-agents-via-java-web-start-is-missing-from-new-node from:http://www.cnblogs.com/EasonJim/p/5997490.html
View DetailsDES 1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES Data Encryption Standard) 。 目前在国内,随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC校验等,均用到DES算法。 DES算法的入口参数有三个:Key、Data、Mode。 其中Key为8个字节共64位,是DES算法的工作密钥; Data也为8个字节64位,是要被加密或被解密的数据; Mode为DES的工作方式,有两种:加密或解密。 DES算法是这样工作的: 如Mode为加密,则用Key 去把数据Data进行加密, 生成Data的密码形式(64位)作为DES的输出结果; 如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。 在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。 通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据的保密性,这正是现在金融交易网络的流行做法。 3DES 3DES是DES加密算法的一种模式,它使用3条64位的密钥对数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法。 3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。 设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密表,这样, 3DES加密过程为:C=Ek3(Dk2(Ek1(P))) 3DES解密过程为:P=Dk1((EK2(Dk3(C))) K1、K2、K3决定了算法的安全性,若三个密钥互不相同,本质上就相当于用一个长为168位的密钥进行加密。多年来,它在对付强力攻击时是比较安全的。若数据对安全性要求不那么高,K1可以等于K3。在这种情况下,密钥的有效长度为112位。 AES AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高。 用AES加密2000年10月,NIST(美国国家标准和技术协会)宣布通过从15种候选算法中选出的一项新的密匙加密标准。Rijndael被选中成为将来的 AES。Rijndael是在1999年下半年,由研究员Joan Daemen 和 Vincent Rijmen 创建的。AES正日益成为加密各种形式的电子数据的实际标准。 美国标准与技术研究院(NIST)于2002年5月26日制定了新的高级加密标准(AES)规范。 AES算法基于排列和置换运算。排列是对数据重新进行安排,置换是将一个数据单元替换为另一个。 AES使用几种不同的方法来执行排列和置换运算。AES是一个迭代的、对称密钥分组的密码,它可以使用128、192和256位密钥,并且用128位(16字节)分组加密和解密数据。 与公共密钥加密使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换和替换输入数据。 算法 Key 位数 可逆? 其它 MD5 没有Key, 有区别16位和32位, 不可逆 (无) SHA (?) (?) 不可逆 (无) RSA 有(公Key,私KEY) (?) 可逆 公、私Key采用不同的加密算法 DES3 有 (?) 可逆 (无) AES 有 (?) 可逆 (无) BASE64 没有KEY (?) 可逆 (无) 哈希函数,比如MD5,SHA,这些都不是加密算法。要注意他们的区别和用途,很多网友都把md5说成是加密算法,这是严重不正确的啊。 哈希函数:MD5,SHA 是没有密钥的,相当与指纹的概念,因此也是不可逆的; md5是128位的,SHA有不同的算法,有128,256等位。。。如SHA-256,SHA-384 然后 就是 Base64,这更加不属于加密算法的范围了,它只是将byte[]数组进行了转换,为什么要转换呢?就是因为很多加密后的密文后者一些特殊的byte[]数组需要显示出来,或者需要进行传递(电子邮件),但是直接转换就会导致很多不可显示的字符,会丢失一些信息,因此就转换位Base64编码,这些都是可显示的字符。所以转换后,长度会增加。它是可逆的。 再就是 3DES,DES 这才是加密算法,因此也是可逆的,加解密需要密钥,也就是你说的key 最后是 RSA ,这是公钥密码,也就是加密和解密密钥不同,也是可逆的。 DES算法: DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,整个算法的主流程图如下: 其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则见下表: 58,50,12,34,26,18,10,2,60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8, 57,49,41,33,25,17, 9,1,59,51,43,35,27,19,11,3, 61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7, 即将输入的第58位换到第一位,第50位换到第2位,…,依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的 左 32位,R0 是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果 为:L0=D58D50…D8;R0= D57D49…D7。 经过16次迭代运算后。得到L16、R16,将此作为输入,进行逆置换,即得到密文输出。逆置换正好是初始置的逆运算,例如,第1位经过初始置换后,处于第40位,而通过逆置换,又将第40位换回到第1位,其逆置换规则如下表所示: 40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31, 38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29, 36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27, 34,2,42,10,50,18,58 26,33,1,41, 9,49,17,57,25, 放大换位表 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10,11, 12,13,12,13,14,15,16,17,16,17,18,19,20,21,20,21, 22,23,24,25,24,25,26,27,28,29,28,29,30,31,32, 1, 单纯换位表 16,7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10, 2,8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25, 在f(Ri,Ki)算法描述图中,S1,S2…S8为选择函数,其功能是把6bit数据变为4bit数据。下面给出选择函数Si(i=1,2……8)的功能表: 选择函数Si S1: 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8, 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0, 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13, S2: 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10, 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5, 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15, 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9, […]
View DetailsC#实现通过Gzip来对数据进行压缩和解压
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
internal static byte[] Compress(byte[] data) { using (var compressedStream = new MemoryStream()) { using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress)) { zipStream.Write(data, 0, data.Length); } return compressedStream.ToArray(); } } internal static byte[] Decompress(byte[] data) { using (var compressedStream = new MemoryStream(data)) { using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress)) { using (var resultStream = new MemoryStream()) { zipStream.CopyTo(resultStream); return resultStream.ToArray(); } } } } |
from:https://www.cnblogs.com/frankyou/p/5910074.html
View DetailsNet C#中枚举的声明格式如下所示:
1 |
[attributes] [modifiers] enum identifier [:base-type] {enumerator-list} [;] |
FlagsAttribute属性就是枚举类型的一项可选属性。它的主要作用是可以将枚举作为位域处理(P.S. C#不支持位域)。所谓位域是单个存储单元内相邻二进制位的集合。通过为枚举添加这个属性,可以改变枚举的一些行为来满足我们的需要。
1 2 3 4 5 |
enum MyFlags { Flag1, Flag2, Flag3, Flag4}; MyFlags myFlag = MyFlags.Flag2 | MyFlags.Flag3; Console.WriteLine(myFlag);//Flag4 |
因为对于整数来说,| 操作就是将其转化为二进制再进行或运算。Flags.Flag2 | Flags.Flag3做的工作实际上是 0001 | 0010 = 0011 = 3再转换成(MyFlags)3就是Flag4了 如果枚举声明如下:
1 2 3 4 5 6 7 |
[FlagsAttribute] enum MyFlags{ Flag1 = 0, //000 Flag2 = 1, //001 Flag3 = 2, //010 Flag4 = 4 //100 }; |
则上述结果为Flag2,Flag3,这样做的意义在于我们可以实现“或”的关系。 就上例而言,myFlag可以更直观的表现为011,因此当我们想要检验它满足哪个枚举值时我们可以使用&操作:
1 2 3 4 5 6 7 8 9 |
if((myFlag & MyFlags.Flag2) == MyFlags.Flag2) { Console.WriteLine("true"); } if((myFlag & MyFlags.Flag3) == MyFlags.Flag3) { Console.WriteLine("true"); } |
011&001 = 001,011&010 = 010,因此这两个if都会成立,这就是这种枚举的意义吧。另外我们应当注意默认初始化的myFlag的值为0,与其作&运算不会有任何结果。 from:https://blog.csdn.net/zhulongxi/article/details/52371853
View Details如果对一个值可以包含多个,那么可以使用枚举,加上Flags 本文告诉大家如何写一个 Flags。 在写前,需要知道一些基础知识,取反、或、与,如果不知道的话,请去看看基础。 当然,这些太复杂了,我也不会在这里解释。 假如有类型
1 2 3 4 5 6 7 8 |
[Flags] <span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> Show { A = <span class="hljs-number">0x00000001</span>, B = <span class="hljs-number">0x00000010</span>, C = <span class="hljs-number">0x00000100</span>, D = <span class="hljs-number">0x00001000</span>, } |
合并多个值 合并多个,使用 |
1 |
<span class="hljs-operator"><span class="hljs-keyword">Show</span> <span class="hljs-keyword">show</span>=<span class="hljs-keyword">Show</span>.A | <span class="hljs-keyword">Show</span>.B</span> |
判断是否存在某个值 一个简单方法是用 HasFlag,但是一个方法是用 &
1 2 3 4 |
<span class="hljs-operator"><span class="hljs-keyword">Show</span> <span class="hljs-keyword">show</span>=<span class="hljs-keyword">Show</span>.A | <span class="hljs-keyword">Show</span>.B;</span> <span class="hljs-operator"><span class="hljs-keyword">show</span>.HasFlag(<span class="hljs-keyword">Show</span>.A);</span> //其他 bool 包含=(<span class="hljs-operator"><span class="hljs-keyword">show</span> & <span class="hljs-keyword">Show</span>.A)!=<span class="hljs-number">0</span>;</span> |
去掉一个值
1 2 |
<span class="hljs-operator"><span class="hljs-keyword">Show</span> <span class="hljs-keyword">show</span>=<span class="hljs-keyword">Show</span>.A | <span class="hljs-keyword">Show</span>.B;</span> <span class="hljs-operator"><span class="hljs-keyword">show</span>=<span class="hljs-keyword">show</span> & (~<span class="hljs-keyword">Show</span>.A);</span> |
取反一个值
1 2 3 4 5 6 7 8 9 10 |
<span class="hljs-operator"><span class="hljs-keyword">Show</span> <span class="hljs-keyword">show</span>=<span class="hljs-keyword">Show</span>.A | <span class="hljs-keyword">Show</span>.B;</span> bool 包含=(<span class="hljs-operator"><span class="hljs-keyword">show</span> & <span class="hljs-keyword">Show</span>.A)!=<span class="hljs-number">0</span>;</span> if(包含) { <span class="hljs-operator"><span class="hljs-keyword">show</span>=<span class="hljs-keyword">show</span> & (~<span class="hljs-keyword">Show</span>.A);</span> } else { <span class="hljs-operator"><span class="hljs-keyword">show</span>=<span class="hljs-keyword">show</span> | <span class="hljs-keyword">Show</span>.A;</span> } |
参见:http://www.cnblogs.com/jhxk/articles/1738831.html
View Details1:安装后,Resharper会用他自己的英文智能提示,替换掉 vs2010的智能提示,所以我们要换回到vs2010的智能提示 2:快捷键。是使用vs2010的快捷键还是使用 Resharper的快捷键呢?我是使用re的快捷键 3: Resharper安装后,会做几件事情,这几件事情对于除此使用者,比较麻烦,因此归纳总结一下,以资参考。 (1)、会将选项——文本编辑器——C#——常规——自动列出成员 这个选择框的勾选去掉。这样当你使用某个方法的时候,便不会提示参数,是一个很郁闷的事情。 可以手动勾上。 (2)、会将选项——文本编辑器——C#——高级——显示实时语义错误、在编辑中用下划线标识错误这两个选项去掉。这个本来没有什么,但是如果卸载了Resharper, vs编辑器变不会实时提示错误。因此卸载Resharper后,需要把这两个选项重新勾选上。 4: use var use implicitly typed local variable declaration 5:按 alt+enter 能解决很多问题。下面是快捷键大全。 6: Alt+F7将你光标所在位置的变量的所有使用以列表的方式显示出来,显示结果的窗体可以像其他窗体那样停靠。 它的优点包括: 可以从所有使用中挑选只显示read usage或者write usage,有时我们只是想知道某个变量在哪里被改变了。找到的位置前的图标也告诉你这点。 可以在下方预览,即使我们列出所有使用,也不想跳转到每个使用它的地方,这时预览可以帮你大忙。 当你在代码编辑器中改动了某些使用时,比如删除了某行,那么在查找结果的窗体中,会用删除线表示出来。 默认的是寻找解决方案中所有的使用,并且按照命名空间来组织,非常便于选择。 我现在已经记不起来在没有Alt+F7之前我是怎么查找的。反正现在我几乎不怎么样Ctrl+F了,除非我忘记了某个变量的名字。如果是这样,多半这个名字需要refactor,那也是Resharper的另一大块功能所在。也许有人对这个功能嗤之以鼻,但是用过CAB的人都知道,订阅和发布某个事件的签名,完全是字符串,如果你不用搜索来找到它的话,你都不知道这个控件的鼠标点下去,到底有多少个处理程序在背后开始工作了。用了Alt+F7来搜索这个字符串,等于在查找背后所有的调用者。 不过提示你,当光标停留在一个类型上时,要慎用Alt+F7,假设是一个string,你应该能想象到得找到多少个使用 7:威力无比的Alt+Enter回车 万能的Alt+Enter能够帮你完成很多编写代码过程中的dirty work,总结起来大概是这么些: 帮你实现某个接口或抽象基类的方法; 提供你处理当前警告的一些建议; 为你提供处理当前错误的一些建议(不一定是真的错误); 为你简化当前的臃肿代码; 8: Ctrl + F11 当我们看别人的代码,或者是看自己的代码的时候,总是觉得代码太多,于是我们就用 region来把代码进行了封装注释,可是这样之后别人看代码就很郁闷,Resharper的 File Structure 功能,就可以把region和你的方法都展示出来。 说了这么多,其实就是把对象浏览器和region的长处结合起来,既可以清晰的分类,又能一目了然的找到需要的方法。Resharper这时帮上你的大忙了。用Ctrl+F11,就弹出一个像右边这样的窗口来。 这里面,按照你的region来显示,这样读你的代码的人也受益了。每个方法的参数,返回值都如UML一样列出来。 如果需要浏览到某个方法,直接双击它的名字; 如果要把某几个方法装进一个新的region,则可以选中方法,点工具栏上的像框的那个图标;点叉则会删除这个region并把相应的方法移到外面来。 如果要调整某个方法的位置,比如把它移到别的region里面去,只需要在这里拖动这个方法即可。 更可喜的是,你想要的从这里浏览、找到所有使用和重构的功能也在这里提供了,在某个方法上右键你就能开始操作。 9:重构才是王道(上) 重构是一种精神,证明你在致力于提供高效的、精炼的、健壮的代码,而不是凌乱的、晦涩的、漏洞百出的代码。 在Visual Studio 2005中,微软第一次提供了重构工具。但是不够,远远不够。我们需要的重构是非常广义的,我们想要对代码进行快速的调整,快到我在想什么我的工具就能做什么。这才是追求重构的境界。所以在这个意义上,几乎Resharper为你提供了巨大的生产力。 Visual Studio 2005提供的重构包括了如下: 封装字段 提取方法 提取接口 提升局部变量 移除参数 重命名 重新排列参数 这些方法在Resharper中全部都支持(但Resharper的重构远不止这些),它们对应的变成了: 封装字段 —— Introduce Field 提取方法 —— Extract Method 提取接口 —— Extract […]
View DetailsTODO 需求 首先我想跟大家分享一下我们团队的代码检查流程。 1. 项目经理随时会检查成员的代码,如果发现有不符合规范的代码,会在注释里面加todo。比如,假设leo的代码不符合规范,那么项目经理就会加注释: //todoleo: refactor below code to match the standard of defining a class in JS 2. 每个成员随时会检查属于自己的todo项,然后修改代码。比如,leo会把项目里所有todoleo的项列出来,然后一个一个检查。检查完了之后,将todo改成review。 3. 项目经理会检查所有的review。如果代码没有问题了,就会删除这个review(曾经的todo);如果代码仍然有问题,那么会再次改成todo。 开启TODO 1. 下载、安装、resharper。下载地址:http://www.jetbrains.com/resharper/。下载之后直接安装,安装后购买或者自行搜索keygen 2. 为每一个团队成员指定唯一的名字,通常为成员名字或者姓的拼音,只要简单易记就可以了。比如todoleo, tododaniel, todoben. 再将这些名字告诉每一个成员。 打开TODO窗口 3. 打开VS, 在菜单栏找到Resharper,然后打开RESHARPER/Windows/todo items。(此时你必须要打开一个项目才看得见) 4. 点击settings(如下图),这是会打开resharper对于todo item的设置。当然,你也可以通过菜单栏resharper-options-tools-todo items打开该设置。 定制TODO 5. 你可以选中一个小伙伴(pattern)或自带的Todo,再点击复制(duplicate),然后后再点击 Edit 修改。你也可以基于下图的设置来修改,注意红框框标记的地方。 TODO预览 6. 设置好了之后点击Save保存,退出设置。此时再打开todo-items,你可以看到filter下方有你自定义的过滤条件了。这些pattern会像resharper自带的todo,bug一样,在注释中加粗显示,特别醒目。 好了,上面就是全部的操作,非常简单吧。 我们团队已经使用这一代码检查流程有几个月了,在实践中发现这一流程非常有用,让每一个成员的工作变得独立,同时又能得到项目经理对代码质量的控制。 from:http://www.cnblogs.com/zhaoqingqing/p/3945107.html
View Details上节中我们谈到了Service Fabric最底层的两个概念,一个是针对硬件层面而言的Node Type和Node。另一个是Application。 Node Type是Node的集合,Node是对部署机器的概念抽象。对Service Fabric而言,Node可以是物理机,虚拟机,甚至现在最主流的Container。 在Node Type上运行的是Application。它是针对系统软件层面的抽象理解。一个Application中包含了多个Micro Service。甚至Service Fabric的所有基础服务,例如FailoverManager Service,Naming Service,也都是Micro Service。 Service Fabric所有分布式特性都对应于Micro Service展开。我们可以动态调整一个Micro Service需要在多少个Node上运行多少个实例来分摊负载压力,或者进行容灾备份。每一个实例都会监听不同的端口,由负载均衡层将请求分布至不同实例上。 实际场景 Stateful Service是其中的一种Micro Service。 在开始介绍Stateful Service之前,让我们来考虑下面这种很常见的业务场景。 你正在考虑实现网站里面的购物车功能。用户登录后会放置一些商品在自己的购物车中。 用户下次登录,前台页面会调用购物车服务,并需要从这个服务重新读取已经保存的购物车数据并用以显示。 如果是你会怎么实现? 如果在用户量不是特别大的一般情况下,我们会在数据库中添加一张购物车表,和用户表进行关联。该购物车表中会有一个用户ID字段,并且记录大量的用户购物车数据。 那么这样就会带来一些后续问题。 如果用户量持续增加,数据库表的性能会持续下降。 数据库表数据需要定期备份,以防数据丢失 如果数据库性能出现问题,需要将表进行拆表处理,甚至需要将表进行分区 购物车系统自身也需要针对数据库的任何调整进行处理,甚至它自身可能也需要做负载均衡 这种问题的根源在于,首先系统本身的设计不是面向可扩展的。另外数据库是一个性能潜在的瓶颈和威胁。 Stateful Service 让我们考虑这样一种全新的架构。 从一开始,购物车系统就由36个子服务来处理所有的请求(36个是因为用户ID的首字母是 0-9 a-z,一共36种)。 用户的请求,会根据用户ID首字母hash至某个特定的子服务来处理。 子服务把购物车数据通过轻量级数据库方式保存在自己内部,并且持久化到自己所在的存储设备上。 每个子服务还有3个备份,这些备份在不停同步保存的数据,同时这些备份永远运行在不同的Node上。 同时只有一个备份作为激活状态来负责处理请求,当激活备份出现问题,另外两个备份根据调度算法激活一个。 容灾子系统再创建一个新的备份,永远保证该子服务有3个健康的备份。 Stateful Service就是这样的一种解决方案。 回到上面的场景,购物车系统就是一个Stateful Service。 36个子系统就是这个Stateful Service的36个实例,我们叫Partition。 每个子系统下的备份就是Replica,一个partition有3个Replica。 当前激活的备份就是Active Replica,两个未激活的待命备份就是Secondary Replica。 同一个Partiion的每个Replica都一定运行在不同的Node上面。 Stateful Service代码通过IReliableCollection<T>,IReliableDictionary<T1, T2>等接口来进行数据保存和内部同步。 此外,Stateful Service还可以实现以下特性。 以上所有的数字都可以重新设置,你可以让购物车系统有几百个partition来负载更大的压力。你甚至可以让每个partition有5个甚至更多Replica来保证更多的健壮性。 外部系统不关心Stateful Service有多少个partition,它们通过partition key来进行调用。Partition Key和具体的对应Partition之间由Service Fabric的底层Micro Service进行解析。例如在你的业务中,你可能有几百万用户,但是只设置5个partition。当调用购物车Stateful Service时,外部系统只需要告知:用户ID(partition key),保存的数据。这个请求会自动根据用户ID及hash算法固定映射到5个partition中的一个。 Stateful Service的数据操作支持事务(Transaction)。因此你可以在失败时回滚(Rollback) 希望以上的介绍可以帮助大家更好的理解Stateful Service。 我们会在后面的章节中介绍Stateful Service的代码示例。 […]
View Details