一、NuGet安装框架
修改代码
效果:
结果:
TopLevel与TopMost属性
frm.TopLevel = false; //Form.TopLevel 获取或设置一个值,该值指示是否将窗体显示为顶级窗口。
frm.TopMost = false; //Form.TopMost 获取或设置一个值,指示该窗体是否应显示为最顶层窗体。 TopMost是级别更高的属性
二、Marshal
三、IntPtr
intPtr类是intPointer的缩写。C#中用来取代指针,也可以说对指针进行封装。指向非托管内存。它也不常用,因为C#项目中指针都被弃用了,那指针的封装——句柄,自然也被弃用了
IntPtr类型对多线程操作是安 IntPtr其实就是 HANDLE,无类型的指针。无类型的指针不能直接使用,需要传给接受它的函数。
IntPtr a = new IntPtr(2121);
int类型与IntPtr类型之间的转换
int _value1 = 10;
int _value2 = 20;
// AllocHGlobal 通过使用指定的字节数从进程的非托管中分配内存
IntPtr _ptr1 = Marshal.AllocHGlobal(sizeof(int));
IntPtr _ptr2= Marshal.AllocHGlobal(sizeof(int));
// 将32位有符号整数写入非托管内存
Marshal.WriteInt32(_ptr1, _value1);
Marshal.WriteInt32(_ptr2, _value2);
int _nv1=Marshal.ReadInt32(_ptr1);
int _nv2=Marshal.ReadInt32(_ptr2);
Marshal.FreeHGlobal(_ptr1); // 释放非托管内存中
Marshal.FreeHGlobal(_ptr2);
Console.WriteLine();
string类型与IntPtr之间的转换
string _str = "aa";
IntPtr _strPtr = Marshal.StringToHGlobalAnsi(_str);
// 将非托管ANSI 字符串复制托管
string _s = Marshal.PtrToStringAnsi(_strPtr);
Marshal.FreeHGlobal(_strPtr);
结构体与IntPtr之间的转换
// 结构体
stuInfo _stu = new stuInfo()
{
_name = "sam",
_gender = "male",
_age = 23,
_hight=34,
};
// 拿到大小
int _size=Marshal.SizeOf(_stu);
IntPtr _p1=Marshal.AllocHGlobal(_size);
// 这一步很重要
Marshal.StructureToPtr(_stu,_p1,true);
stuInfo _stu2 = (stuInfo)Marshal.PtrToStructure(_p1,typeof(stuInfo));
Console.WriteLine(_stu2._name);
Console.WriteLine(_stu2._gender);
Console.WriteLine(_stu2._age);
Console.WriteLine(_stu2._hight);
获得数组的指针
int[] _ary = new int[] { 1, 2, 3 };
IntPtr inp = Marshal.UnsafeAddrOfPinnedArrayElement(_ary, 0);
IntPtr inp1 = Marshal.UnsafeAddrOfPinnedArrayElement(_ary, 1);
IntPtr inp2 = Marshal.UnsafeAddrOfPinnedArrayElement(_ary, 2);
//内存地址以字节为单位,第一个元素地址为:n,第二个为:n+数据类型的字节数。int32是4个字节,那么元素相邻址之间差4
//每次运行结果的内存地址都不一样!!!但地址却都相差4【系统随机分配内存】
Console.WriteLine(inp.ToString());//输出的就是一串数字,就是内存地址。输出结果:n
Console.WriteLine(inp1.ToString());//输出的就是一串数字,就是内存地址。输出结果:n+4
Console.WriteLine(inp2.ToString());//输出的就是一串数字,就是内存地址。输出结果:n+8
获取某个变量的指针
unsafe
这里就要用到C#中的指针,用unsafe {}关键字,并设置:项目属性——>生成——>勾选“允许不安全代码”
四、BackgroundWorker
BackgroundWorker
是 .NET Framework 中一个用于简化多线程操作的类。但它的功能有限。它允许在后台线程中执行耗时的操作,而不会阻塞用户界面的线程。这样,程序的用户界面可以继续响应用户的操作,同时在后台进行处理。它封装了线程的创建和管理,并提供了事件来处理线程的状态变化
使用
创建实例:
创建 BackgroundWorker
对象的实例。
BackgroundWorker worker = new BackgroundWorker();
设置事件处理程序:
为 DoWork
事件、RunWorkerCompleted
事件和(可选的)ProgressChanged
事件设置事件处理程序。
worker.DoWork += Worker_DoWork;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
worker.ProgressChanged += Worker_ProgressChanged;
worker.WorkerReportsProgress = true; // 如果需要报告进度
定义事件处理程序:
DoWork
事件处理程序用于执行后台任务。RunWorkerCompleted
事件处理程序用于处理任务完成后的操作(例如更新 UI)。ProgressChanged
事件处理程序用于处理后台任务报告的进度
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
// 执行耗时的操作
// 可以通过 e.Argument 传递参数
// 通过 (sender as BackgroundWorker).ReportProgress(percentage) 来报告进度
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// 处理任务完成后的操作
// e.Result 可以访问任务结果
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// 更新进度
// e.ProgressPercentage 获取进度百分比
}
启动后台任务:
调用 RunWorkerAsync
方法来启动任务
worker.RunWorkerAsync();
示例:
public static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
BackgroundWorker _backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += Worker_DoWork;
_backgroundWorker.RunWorkerCompleted += Worker_RunWorkerCompleted;
_backgroundWorker.ProgressChanged += Worker_ProgressChanged;
_backgroundWorker.WorkerReportsProgress = true; // 如果需要报告进度
_backgroundWorker.RunWorkerAsync();
}
private static void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Worker_DoWork(object sender, DoWorkEventArgs e) 11");
// 执行耗时的操作
// 可以通过 e.Argument 传递参数
// 通过 (sender as BackgroundWorker).ReportProgress(percentage) 来报告进度
}
private static void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 222");
// 处理任务完成后的操作
// e.Result 可以访问任务结果
}
private static void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Worker_ProgressChanged(object sender, RunWorkerCompletedEventArgs e) 3333");
// 更新进度
// e.ProgressPercentage 获取进度百分比
}
结果:
五、DateTime类常用的方法
C# DateTime:日期、日期差、时间、时间差_c# 日期差-CSDN博客
常用属性
Date:获取不包含时间的 DateTime
对象,即日期部分。
DateTime _today = DateTime.Now.Date; //今天的日期
TimeOfDay:获取 DateTime
对象表示的时间部分(TimeSpan
对象)
TimeSpan timeOfDay = DateTime.Now.TimeOfDay;
DayOfWeek:获取 DateTime
对象表示的星期几。
DayOfWeek dayOfWeek = DateTime.Now.DayOfWeek;
Day、Month、Year:获取 DateTime
对象中的日、月、年部分。
int day = DateTime.Now.Day;
int month = DateTime.Now.Month;
int year = DateTime.Now.Year;
Hour、Minute、Second:获取 DateTime
对象中的小时、分钟、秒部分。
int hour = DateTime.Now.Hour;
int minute = DateTime.Now.Minute;
int second = DateTime.Now.Second;
常用方法
Add
AddDays(double value)
:返回一个新的DateTime
对象,表示当前日期加上指定的天数。AddHours(double value)
:返回一个新的DateTime
对象,表示当前日期加上指定的小时数。AddMinutes(double value)
:返回一个新的DateTime
对象,表示当前日期加上指定的分钟数。AddSeconds(double value)
:返回一个新的DateTime
对象,表示当前日期加上指定的秒数。AddMonths(int months)
:返回一个新的DateTime
对象,表示当前日期加上指定的月份数。AddYears(int value)
:返回一个新的DateTime
对象,表示当前日期加上指定的年份数。
DateTime now = DateTime.Now; // 今天的时间
DateTime tomorrow = now.AddDays(1); // 今天+1 =明天
DateTime nextWeek = now.AddDays(7); // 今天+7=下周
Subtract
Subtract(DateTime value)
:返回一个TimeSpan
对象,表示当前DateTime
对象与指定日期之间的时间间隔。Subtract(TimeSpan value)
:返回一个新的DateTime
对象,表示当前日期减去指定的时间间隔。
TimeSpan duration = now.Subtract(tomorrow); // 今天和明天的时间间隔=1
DateTime pastDate = now.Subtract(TimeSpan.FromDays(10));
ToString
ToString()
:将DateTime
对象转换为默认格式的字符串。ToString(string format)
:将DateTime
对象转换为指定格式的字符串。常用格式包括"yyyy-MM-dd"
,"MM/dd/yyyy"
,"dddd, MMMM dd, yyyy"
等。
string dateStr = now.ToString("yyyy-MM-dd");
TryParse
TryParse(string s, out DateTime result)
:尝试将字符串转换为DateTime
对象,返回一个布尔值指示转换是否成功
if (DateTime.TryParse("2023-09-17", out DateTime parsedDate))
{
// 使用 parsedDate
}
Now 和 UtcNow
DateTime.Now
:获取当前本地日期和时间。DateTime.UtcNow
:获取当前的 UTC 日期和时间DateTime localNow = DateTime.Now; DateTime utcNow = DateTime.UtcNow;
Compare
Compare(DateTime t1, DateTime t2)
:比较两个DateTime
对象,返回一个指示它们的相对排序顺序的整数。CompareTo(DateTime value)
:比较当前DateTime
对象与指定的DateTime
对象int comparison = DateTime.Compare(now, pastDate);
IsLeapYear 和 DaysInMonth
IsLeapYear(int year)
:确定指定的年份是否是闰年。DaysInMonth(int year, int month)
:获取指定年份和月份的天数
bool isLeap = DateTime.IsLeapYear(2024);
int days = DateTime.DaysInMonth(2024, 2);