• C# 常用功能整合-1


    -目录

    线程

    MD5加密

    计算两个时间间隔

    数组等比例缩放

    时间加减

    字符串转换DateTime类型

    Net5添加管理员权限 以管理员身份运行

    Task执行任务,等待任务完成

    用“\”分割字符

    实现模拟键盘按键

    代码运行耗时

    通过反射获取和设置指定的属性

    特性玩法1

    泛型玩法2

    泛型


    线程

    在运用多线程技术之前,先得理解什么是线程。
    那什么是线程呢?说到线程就不得不先说说进程。通俗的来讲,进程就是个应程序开始运行,那么这个应用程序就会存在一个属于这个应用程序的进程。
    那么线程就是进程中的基本执行单元,每个进程中都至少存在着一个线程,这个线程是根据进程创建而创建的,所以这个线程我们称之为主线程。
    那么多线程就是包含有除了主线程之外的其他线程。
    如果一个线程可以执一个任务,那么多线程就是可以同时执行多个任务。
     

    线程的基本用法:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Data;
    5. using System.Drawing;
    6. using System.Linq;
    7. using System.Text;
    8. using System.Threading;
    9. using System.Threading.Tasks;
    10. using System.Windows.Forms;
    11. namespace 线程
    12. {
    13. public partial class Form1 : Form
    14. {
    15. private List ThreadPool = new List();
    16. public Form1()
    17. {
    18. InitializeComponent();
    19. }
    20. private void Form1_Load(object sender, EventArgs e)
    21. {
    22. Thread thread = new Thread(TestThread);
    23. ThreadPool.Add(thread);
    24. thread.Start();
    25. }
    26. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    27. {
    28. if(ThreadPool.Count > 0)
    29. {
    30. foreach (Thread thread in ThreadPool)
    31. {
    32. if (thread.IsAlive)//当前线程是否终止
    33. {
    34. thread.Abort();//终止线程
    35. }
    36. }
    37. }
    38. }
    39. private void TestThread()
    40. {
    41. for (int i = 0; i <= 10; i++)
    42. {
    43. Console.WriteLine("输出:" + i);
    44. Thread.Sleep(500);
    45. }
    46. }
    47. private void Button_Test_Click(object sender, EventArgs e)
    48. {
    49. if (ThreadPool.Count > 0)
    50. {
    51. foreach (Thread thread in ThreadPool)
    52. {
    53. Console.WriteLine("当前线程是否终止:" + thread.IsAlive);
    54. }
    55. }
    56. }
    57. }
    58. }

    MD5加密

    1. ///
    2. /// 计算md5
    3. ///
    4. ///
    5. ///
    6. private string CalcMD5(string str)
    7. {
    8. byte[] buffer = Encoding.UTF8.GetBytes(str);
    9. using (MD5 md5 = MD5.Create())
    10. {
    11. byte[] md5Bytes = md5.ComputeHash(buffer);
    12. StringBuilder sb = new StringBuilder();
    13. for (int i = 0; i < md5Bytes.Length; i++)
    14. {
    15. sb.Append(md5Bytes[i].ToString("x2"));//X2时,生成字母大写MD5
    16. }
    17. return sb.ToString();
    18. }
    19. }

    计算两个时间间隔

    代码

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace Utils
    7. {
    8. public class TimeInterval
    9. {
    10. ///
    11. /// 计算两个时间间隔的时长
    12. ///
    13. /// 返回的时间类型
    14. /// 开始时间
    15. /// 结束时间
    16. /// 返回间隔时间,间隔的时间类型根据参数 TimeType 区分
    17. public static double GetSpanTime(TimeType TimeType, DateTime StartTime, DateTime EndTime)
    18. {
    19. TimeSpan ts1 = new TimeSpan(StartTime.Ticks);
    20. TimeSpan ts2 = new TimeSpan(EndTime.Ticks);
    21. TimeSpan ts = ts1.Subtract(ts2).Duration();
    22. //TimeSpan ts = EndTime - StartTime;
    23. double result = 0f;
    24. switch (TimeType)
    25. {
    26. case TimeType.MilliSecond:
    27. result = ts.TotalMilliseconds;
    28. break;
    29. case TimeType.Seconds:
    30. result = ts.TotalSeconds;
    31. break;
    32. case TimeType.Minutes:
    33. result = ts.TotalMinutes;
    34. break;
    35. case TimeType.Hours:
    36. result = ts.TotalHours;
    37. break;
    38. case TimeType.Days:
    39. result = ts.TotalDays;
    40. break;
    41. }
    42. return result;
    43. }
    44. }
    45. ///
    46. /// 时间类型
    47. ///
    48. public enum TimeType
    49. {
    50. ///
    51. /// 毫秒
    52. ///
    53. MilliSecond,
    54. ///
    55. ///
    56. ///
    57. Seconds,
    58. ///
    59. /// 分钟
    60. ///
    61. Minutes,
    62. ///
    63. /// 小时
    64. ///
    65. Hours,
    66. ///
    67. ///
    68. ///
    69. Days,
    70. ///
    71. ///
    72. ///
    73. Months
    74. }
    75. }

    调用:

    1. class Program
    2. {
    3. static void Main(string[] args)
    4. {
    5. DateTime dateTime1 = DateTime.Now;
    6. Thread.Sleep(3000);
    7. DateTime dateTime2 = DateTime.Now;
    8. double timeDifference = TimeInterval.GetSpanTime(timeType, dateTime1, dateTime2);
    9. Console.WriteLine(string.Format("{0} {1}", timeDifference, timeType.ToString()));
    10. Console.ReadKey();
    11. }
    12. }

    输出:

    3 Seconds

    数组等比例缩放

    新建一个C#控制台项目,要新建.NetFramework类型的,不然下面代码中的某些API无法使用。

    代码:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace Test1
    7. {
    8. class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. List<double> resultList = ScaleConversion(new List<double>() { 230, 2453, 4353, 65 }, 10);
    13. string value = string.Empty;
    14. for (int i = 0; i < resultList.Count; i++)
    15. {
    16. value += string.Format("{0},", resultList[i]);
    17. }
    18. Console.WriteLine(value);
    19. Console.ReadKey();
    20. }
    21. ///
    22. /// 将数组等比例缩放
    23. ///
    24. /// 数组
    25. /// 缩放的最大值,最小值默认为0
    26. /// 缩放后的数组
    27. public static List<double> ScaleConversion(List<double> valueList, int maxScale)
    28. {
    29. if (valueList == null || valueList.Count == 0)
    30. {
    31. Console.WriteLine("valueList 不能为空");
    32. return null;
    33. }
    34. if (maxScale < 10)
    35. {
    36. Console.WriteLine("等比例的最大值不能小于10");
    37. return null;
    38. }
    39. double max = valueList.Max();
    40. double factor = Math.Round(max / maxScale, 2);//系数
    41. List<double> result = new List<double>();
    42. for (int i = 0; i < valueList.Count; i++)
    43. {
    44. result.Add(Math.Round(valueList[i] / factor, 2));
    45. }
    46. if (result.Count > 0)
    47. return result;
    48. return null;
    49. }
    50. }
    51. }

    运行后,结果是:0.53,5.64,10,0.15,

    这里是将10做为缩放比例中的最大值,有兴趣的读者可以自己算一下是否正确。

    时间加减

    代码:

    1. using System;
    2. namespace Util
    3. {
    4. public class TimeCompute
    5. {
    6. ///
    7. /// 时间间隔
    8. ///
    9. /// 时间1
    10. /// 时间2
    11. /// 同一天的相隔的分钟的整数部分
    12. public static int DateDiff(DateTime DateTime1, DateTime DateTime2)
    13. {
    14. TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
    15. TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
    16. TimeSpan ts = ts1.Subtract(ts2).Duration();
    17. return Convert.ToInt32(ts.TotalMinutes);
    18. }
    19. ///
    20. /// 时间相加
    21. ///
    22. /// 时间1
    23. /// 时间2
    24. /// 时间和
    25. public static DateTime DateSum(DateTime DateTime1, DateTime DateTime2)
    26. {
    27. DateTime1 = DateTime1.AddHours(DateTime2.Hour);
    28. DateTime1 = DateTime1.AddMinutes(DateTime2.Minute);
    29. DateTime1 = DateTime1.AddSeconds(DateTime2.Second);
    30. return DateTime1;
    31. }
    32. ///
    33. /// 根据秒数得到 DateTime
    34. ///
    35. /// 秒数
    36. /// 以1970-01-01为日期的时间
    37. public static DateTime GetDateTimeBySeconds(double seconds)
    38. {
    39. return DateTime.Parse(DateTime.Now.ToString("1970-01-01 00:00:00")).AddSeconds(seconds);
    40. }
    41. ///
    42. /// 根据 DateTime 得到秒数
    43. ///
    44. /// 时间
    45. /// 秒数
    46. public static double GetDateTimeBySeconds(DateTime dateTime)
    47. {
    48. return (Convert.ToInt32(dateTime.Hour) * 3600) + (Convert.ToInt32(dateTime.Minute) * 60) + Convert.ToInt32(dateTime.Second);
    49. }
    50. }
    51. }

    字符串转换为时间

    这里也可以使用 DateTime.Parse 进行转换,如果时间字符串写的不齐,只有时间,没有日期,就会以当前的日期和字符串中的时间进行组合

    DateTime dt = Convert.ToDateTime("1:00:00");

    两个时间相减

    1. DateTime t1 = DateTime.Parse("2007-01-01");
    2. DateTime t2 = DateTime.Parse("2006-01-01");
    3. TimeSpan t3 = t1 - t2;

    字符串转换DateTime类型

    代码

    1. //下面这两种字符串写法都可以
    2. string timer = "2022-02-02 18:15:58";
    3. string timer = "2022/2/18 18:18:26";
    4. DateTime dateTime = Convert.ToDateTime(timer);
    5. Console.WriteLine(dateTime);

    Net5添加管理员权限 以管理员身份运行

    在 项目 上 添加新项 选择“应用程序清单文件” 然后单击 添加 按钮


    添加后,默认打开app.manifest文件,将: 


     
    修改为:

     重新生成项目,再次打开程序时就会提示 需要以管理员权限运行。
     

    Task执行任务,等待任务完成

    代码:

    1. //任务
    2. Func<int> Funcs = () =>
    3. {
    4. Console.WriteLine("任务开始");
    5. return 1 + 1;
    6. };
    7. //执行任务
    8. Task<int> printRes = Task.Run(Funcs);
    9. //等待任务完成
    10. printRes.GetAwaiter().OnCompleted(() =>
    11. {
    12. Console.WriteLine("异步执行结果:" + printRes.Result);
    13. });

    运行:

    任务开始
    异步执行结果:2

    用“\”分割字符

    1. string Chars = @"\";
    2. string Text = @"ddsdd\dddds";
    3. string[] Arr = Text.Split(new[] { Chars },StringSplitOptions.None);
    4. //结果:Arr[0] = "ddsdd, Arr[1] = dddds

    实现模拟键盘按键

    1.发送字符串,这里的字符串可以为任意字符

    1. private void button1_Click(object sender,EventArgs e)
    2. {
    3. textBox1.Focus();
    4. SendKeys.Send("{A}");
    5. }

    2.模拟组合键:CTRL + A

    1. private void button1_Click(object sender,EventArgs e)
    2. {
    3. webBrowser1.Focus();
    4. SendKeys.Send("^{A}");
    5. }

    3.SendKeys.Send  异步模拟按键(不阻塞UI)

    按键参考:虚拟键码 (Winuser.h) - Win32 apps | Microsoft Docs

    1. [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
    2. //bvk 按键的虚拟键值,如回车键为 vk_return, tab 键为 vk_tab(其他具体的参见附录)
    3. //bScan 扫描码,一般不用设置,用 0 代替就行;
    4. //dwFlags 选项标志,如果为 keydown 则置 0 即可,如果为 keyup 则设成 "KEYEVENTF_KEYUP";
    5. //dwExtraInfo 一般也是置 0 即可。
    6. public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
    7. private void button1_Click(object sender,EventArgs e)
    8. {
    9. textBox1.Focus();
    10. keybd_event(Keys.A, 0, 0, 0);
    11. }

    4.模拟组合键:CTRL + A

    1. public const int KEYEVENTF_KEYUP = 2;
    2. private void button1_Click(object sender,EventArgs e)
    3. {
    4. webBrowser1.Focus();
    5. keybd_event(Keys.ControlKey,0,0,0);
    6. keybd_event(Keys.A,0,0,0);
    7. keybd_event(Keys.ControlKey,KEYEVENTF_KEYUP,0,0);
    8. }

    5.上面两种方式都是全局范围呢,现在介绍如何对单个窗口进行模拟按键

    下面代码没测试过,不知道有用没有

    1. [DllImport("user32.dll",EntryPoint = "PostMessageA",SetLastError = true)]
    2. public static extern int PostMessage(IntPtr hWnd,int Msg,Keys wParam,int lParam);
    3. public const int WM_CHAR = 256;
    4. private void button1_Click(object sender,EventArgs e)
    5. {
    6. textBox1.Focus();
    7. PostMessage(textBox1.Handle,256,Keys.A,2);
    8. }
    1. public const int WM_KEYDOWN = 256;
    2. public const int WM_KEYUP = 257;
    3. private void button1_Click(object sender,0)
    4. {
    5. PostMessage(webBrowser1.Handle,WM_KEYDOWN,0);
    6. }

    代码运行耗时

    这个功能在代码实现上比较简单,几行代码就可以做到

    声明计时器

    1. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
    2. stopwatch.Start();

    暂停计时器,输出时间

    1. stopwatch.Stop();
    2. Console.WriteLine(stopwatch.Elapsed.Minutes + "分" + stopwatch.Elapsed.Seconds + "秒");

    如果需要分段多次计时,那么就需要将计时器清空

    1. stopwatch.Stop();
    2. stopwatch.Reset();
    3. stopwatch.Start();

    通过反射获取和设置指定的属性

    1. public class Program
    2. {
    3. //定义类
    4. public class MyClass
    5. {
    6. public int Property1 { get; set; }
    7. }
    8. static void Main()
    9. {
    10. MyClass tmp_Class = new MyClass();
    11. tmp_Class.Property1 = 2;
    12. //获取类型
    13. Type type = tmp_Class.GetType();
    14. //获取指定名称的属性
    15. System.Reflection.PropertyInfo propertyInfo = type.GetProperty("Property1");
    16. //获取属性值
    17. int value_Old = (int)propertyInfo.GetValue(tmp_Class, null);
    18. Console.WriteLine(value_Old);
    19. //给对应属性赋值
    20. propertyInfo.SetValue(tmp_Class, 5, null);
    21. int value_New = (int)propertyInfo.GetValue(tmp_Class, null);
    22. Console.WriteLine(value_New);
    23. Console.ReadLine();
    24. }
    25. }

    特性玩法1

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Reflection;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. namespace 特性
    8. {
    9. public class Program
    10. {
    11. static void Main(string[] args)
    12. {
    13. //获取程序集所有的类
    14. Type[] types = typeof(Program).Assembly.GetTypes();
    15. //遍历所有的类
    16. foreach (Type t in types)
    17. {
    18. //遍历当前类所有的方法
    19. foreach (MethodInfo method in t.GetMethods())
    20. {
    21. //遍历当前方法的上的所有特性
    22. foreach (Attribute attr in method.GetCustomAttributes())
    23. {
    24. //如果特性是GameSystem
    25. if (attr is GameSystem)
    26. {
    27. //实例化当前类的实例
    28. object reflectTest = Activator.CreateInstance(t);
    29. //获取当前方法的名字
    30. MethodInfo methodInfo = t.GetMethod(method.Name);
    31. //执行当前方法
    32. methodInfo.Invoke(reflectTest, null);
    33. }
    34. }
    35. }
    36. }
    37. Console.ReadKey();
    38. }
    39. }
    40. //自定义特性类
    41. [AttributeUsage(AttributeTargets.All)]
    42. public class GameSystem : Attribute//正常格式是GameSystemAttribute这样的
    43. {
    44. public GameSystem() { }
    45. }
    46. //自定义一个player类
    47. public class player
    48. {
    49. //GameSystem特性类的名字,如果定义的时候特性类的名字是这样GameSystemAttribute打上特性也是一样的
    50. [GameSystem]
    51. public void Start()
    52. {
    53. Console.WriteLine("GameSystem start");
    54. }
    55. [GameSystem]
    56. public void Updata()
    57. {
    58. Console.WriteLine("GameSystem updata");
    59. }
    60. public void Awaken()
    61. {
    62. Console.WriteLine("Awaken~~~~~~");
    63. }
    64. }
    65. }

    运行:

    泛型玩法2

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Reflection;
    5. using System.Text;
    6. using System.Threading.Tasks;
    7. namespace Test_Console
    8. {
    9. class Program
    10. {
    11. static void Main(string[] args)
    12. {
    13. Test test = new Test();
    14. test.Print().Run();
    15. test.Print().Run();
    16. //test.Print().ChickenFlew();//报错,因为没实现Movement接口
    17. Console.ReadKey();
    18. }
    19. }
    20. public class Test
    21. {
    22. private Dictionary<string, object> ObjectDictionary = new Dictionary<string, object>();
    23. public T Print<T>() where T: class, Movement, new()
    24. {
    25. Type t = typeof(T);
    26. string fullName = t.FullName;
    27. if (ObjectDictionary.ContainsKey(fullName))
    28. {
    29. return (T)ObjectDictionary[fullName];
    30. }
    31. else
    32. {
    33. object obj = Activator.CreateInstance(t);
    34. ObjectDictionary.Add(fullName, obj);
    35. return (T)obj;
    36. }
    37. }
    38. }
    39. public interface Movement
    40. {
    41. void Run();
    42. }
    43. public class Dog : Movement
    44. {
    45. public void Run()
    46. {
    47. Console.WriteLine("狗跑了");
    48. }
    49. }
    50. public class Cat : Movement
    51. {
    52. public void Run()
    53. {
    54. Console.WriteLine("猫跑了");
    55. }
    56. }
    57. public class Chook
    58. {
    59. public void ChickenFlew()
    60. {
    61. Console.WriteLine("鸡飞了");
    62. }
    63. }
    64. }

    运行:

    泛型

    泛型的意义在于免去了类型之间互相转换的系统开销,和同类方法的重载,
    比如,Add方法你要重载两个方法(int和double)或者更多方法,用范型只用写一个Add方法就可以完成int,double,float......等等的相加,
    再如,集合的操作,没有往往是弱类型(object),而用范型可以直接是强类型,无需转换之间的开销,节省了资源,

    代码:
     

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace _01_自定义泛型
    7. {
    8. class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. // 泛型类
    13. MyClass1<string> myClass = new MyClass1<string>();
    14. myClass.SayHi("嘻嘻嘻");
    15. // 泛型委托
    16. MyGenericDelegate<string> md = m1;
    17. md("泛型委托");
    18. Console.ReadKey();
    19. }
    20. public static void m1(string msg)
    21. {
    22. Console.WriteLine(msg);
    23. }
    24. ///
    25. /// 泛型类
    26. ///
    27. ///
    28. public class MyClass1<T>
    29. {
    30. public void SayHi(T arg)
    31. {
    32. Console.WriteLine(arg);
    33. }
    34. }
    35. public class MyClass2
    36. {
    37. ///
    38. /// 泛型方法
    39. ///
    40. ///
    41. ///
    42. public void SayHi<T>(T msg)
    43. {
    44. Console.WriteLine(msg);
    45. }
    46. }
    47. ///
    48. /// 泛型接口
    49. ///
    50. ///
    51. public interface IFace<T>
    52. {
    53. void SayHi(T msg);
    54. }
    55. //-----实现泛型接口有两种情况-----
    56. ///
    57. /// 1.普通类实现泛型接口
    58. ///
    59. public class MyClass3 : IFace<string>
    60. {
    61. public void SayHi(string msg)
    62. {
    63. Console.WriteLine(msg);
    64. }
    65. }
    66. ///
    67. /// 2.泛型类继承泛型接口
    68. ///
    69. ///
    70. public class MyClass4<T> : IFace<T>
    71. {
    72. public void SayHi(T msg)
    73. {
    74. Console.WriteLine(msg);
    75. }
    76. }
    77. ///
    78. /// 泛型约束
    79. ///
    80. public class MyClass5<T,K,V,W,X>
    81. where T : struct // 约束T必须是值类型
    82. where K : class // 约束K必须是引用类型
    83. where V : IFace<T> // 约束V必须实现IFace接口
    84. where W: K // W必须是K类型,或者K类型的子类
    85. where X : class,new() // X必须是引用类型,并且有一个无参数的构造函数,当有多个约束时,new()必须写在最后
    86. {
    87. public void Add(T num)
    88. {
    89. Console.WriteLine(num);
    90. }
    91. }
    92. ///
    93. /// 泛型委托
    94. ///
    95. ///
    96. ///
    97. public delegate void MyGenericDelegate<T>(T args);
    98. }
    99. }

    end

  • 相关阅读:
    k8s资源管理操作——陈述式管理方式
    Tensor-LLM简单介绍
    CNN鲜花分类
    Linux 性能优化之使用 Tuned 配置优化方案
    C#使用正则表达式 判断string 字符串是否包含汉字
    OpenCV 05(图像的算术与位运算)
    Flutter高仿微信-第57篇-添加好友
    Spring编程常见错误50例-Spring AOP常见错误(上)
    lc--655:输出二叉树
    【背景渐变】 —— 就算没接触过也能 一遍学会哦
  • 原文地址:https://blog.csdn.net/qq_38693757/article/details/125989568