返回首页

高速

字典查找键值是否存在

字典.ContainsKey("键值")

高速

字典对象初始化

Dictionary<string, string> UseFor = new Dictionary<string,string> { {"station","站点"},{"city","城市"},{"province","省"} };

高速

字典对象读取
只能用循环迭代 如foreach

高速

复制文件
System.IO.File.Copy(oldFilePath, newFilePath, false);

高速

追加文件内容
StreamWriter sw = File.AppendText(Path); sw.Write(strings); sw.Flush(); sw.Close(); sw.Dispose();

Table处理-该行已属于另一个表

错误原因:
dt.Rows.Add(dr)
解决方法:
dt.Rows.Add(dr.ItemArray)

Table处理-输入数组长度大于此表中的列数(可能是DataTable没加列)

DataTable newdt = dt.Clone();
不用调用Clear方法 Clone后无数据,只有表结构(列)

高速

服务端相对路径转绝对路径

Server.MapPath(path);
e.g "/Solution/123.txt" 转为 F:\Solution\123.txt

知识点

float和double的区别

单精度浮点数在机内存占4个字节,有效数字8位(小数点后第8位四舍五入),表示范围:-3.40E+38~3.40E+38
双精度浮点数在机内存占8个字节,有效数字16位,表示范围:-1.79E+308~-1.79E+308
一般来说,CPU处理单精度浮点数的速度比处理双精度浮点数快, 如果不声明,默认小数为double类型,所以如果要用float的话,必须进行强转
e.g float a=1.3; 会编译报错,正确的写法 float a = (float)1.3;或者float a = 1.3f;(f或F都可以不区分大小写)
1.java中3*0.1==0.3将会返回什么?true还是false?    fale,因为浮点数不能完全精确的表示出来,一般会损失精度。   2.java中float f = 3.4;是否正确?    不正确,3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于向下转型会造  成精度损失,因此需要强制类型转换float f = (float)3.4;或者写成 float f = 3.4f;才可以。

高速

诊断类使用

System.Diagnostics.Stopwatch swTimeCost = new System.Diagnostics.Stopwatch(); swTimeCost.Start(); swTimeCost.Stop(); swTimeCost.ElapsedMillionseconds //时间差 swTimeCost.Restart(); //restart后可继续start

高速

文件大小计算

public string GetFileSize(string sFileFullName) { FileInfo fiInput = new FileInfo(sFileFullName); double len = fiInput.Length; string[] sizes = { "B", "KB", "MB", "GB" }; int order = 0; while (len >= 1024 && order + 1 < sizes.Length) { order++; len = len / 1024; } string filesize = String.Format("{0:0.##} {1}", len, sizes[order]); return filesize; }

知识点

泛型约束

class MyClass<T> where T : struct //T只能是值类型 class MyClass<T> where T : class //T只能是引用类型 class MyClass<T> where T : new() //T必须有公共的无参构造函数 class MyClass<T> where T : Person //T必须继承自Person class MyClass<T> where T : IDisposable //T必须继承自IDisposable 其他:对于单个T可以有多个约束,也可以对多个参数进行约束,多约束要注意逻辑(不同逻辑中是否生效)

知识点

反射PropertyInfo使用

PropertyInfo 首先是用在实体类上的,获取实体类上的公开属性,或者是泛型T类型。一般做转换用,可以从Dictionary,SqlDataReader动态转换为具体实体
Person per = new Person(); PropertyInfo[] properties= per.GetType().GetProperties();//获取所有公开属性 properties.Length;//所有属性的个数 properties[0].Name;//属性名称 properties[0].PropertyType;//属性类型 properties[0].GetValue(per);//获取该属性数据 properties[0].SetValue(per, 2);//设置该属性值 //泛型中可以这样创建对象 var p2 = Activator.CreateInstance<T>();

知识点

程序中用颜色表示的代码 Color.FromArgb(0, 0, 0); Color.White; Color c= Color.FromName("#00FF00");

知识点

DataTable转换为集合

public List<T> FillModel(DataTable dt) { if (dt == null || dt.Rows.Count == 0) { return null; } List<T> modelList = new List<T>(); foreach (DataRow dr in dt.Rows) { //T model = (T)Activator.CreateInstance(typeof(T)); T model = new T(); for (int i = 0; i < dr.Table.Columns.Count; i++) { PropertyInfo propertyInfo = model.GetType().GetProperty(dr.Table.Columns[i].ColumnName); if (propertyInfo != null && dr[i] != DBNull.Value) propertyInfo.SetValue(model, dr[i], null); } modelList.Add(model); } return modelList; }

知识点

委托和事件简介

1.委托是有签名的,事件没有,他由委托定义
2.委托定义public delegate void MyEventHandler(object sender, MyEventArgs e);
3.事件定义private event MyEventHandler myevent;
4.事件处理函数一般起名On....

创建随机函数Random对象 一定要放在循环外面

在循环内容使用时,可以用random.next() 方法。如果直接在循环内使用New Random().Next(1,100)每次生成的随机数是相同的

知识点

枚举类型和值的转换

枚举类型和它对应的值可以直接通过强制类型转换获取,比如定义枚举类型
enum FileType { Increase=1, Covered=2 }
由数值转换为枚举(FileType)2;由枚举转换为数值(int)FileType.Increase;枚举类型还可以调用GetHashCode方法返回值类型

知识点

实例化委托的三种方法

1.声明委托,声明函数,把函数入口给委托
声明委托:delegate int MathHandler(int num)
声明函数:public int methord(int num){return num *2;}
把函数入口给委托变量: MathHandler handler=methord;
注意委托是类型,不是变量,要使用应该是MathHandler handler;
2.匿名委托,实例化委托实例
MathHandler handler=delegate(int num){return num*2;}
3.lambda表达式实例化委托
MathHandler handler= number=>number *2;
系统中预定义的几个委托类型:
Func<T,TResult>,Action<T>, delegate bool System.Predicate<in T>(T obj)

知识点

方法参数中的this/扩展方法

这种用法说明该方法是扩展方法!这个扩展方法在静态类中声明,定义一个静态方法
第一个参数定义它的扩展类型,后面如果有参数,则代表调用时的参数
如下定义:
public static class MyWayClass { public static void MyWay(this string str) { Console.WriteLine("hi"); } }
该定义扩展了String类,为它增加了MyWay方法,调用时它没有参数
string str = "sss";
str.MyWay();//输出hi
那如何为它指定参数呢,就是在定义MyWay方法中再增加一个参数如:
public static class MyWayClass { public static void MyWay(this string str,string s1) { Console.WriteLine(s1); } }
则调用时, string str = "sss";
str.MyWay(str); //输出sss
可以看到,最外面的静态类可以随便指定,关键字this后的类型就是要扩展的类型,该方法就是扩展的方法。

知识点

Enumerable.Repeat 用法

定义:IEnumerable<TResult> Enumerable.Repeat<TResult>(TResult element,int count)
作用:把当前element类复制count份(数据完全相同),放到一个集合中
e.g : var list=Enumerable.Repeat(myClass,2);
注意:复制出来的对象指向原有的对象,所以该对象如果修改则原有对象也会修改,复制多份也是一样的

知识点

字符串比较不区分大小写

使用到了StringComparison.OrdinalIgnoreCase
e.g
string a = "123Abc"; string b = "123abc"; bool flag= a.Equals(b,StringComparison.OrdinalIgnoreCase);
输出:true

知识点

C#中的多态

1.父级方法必须为virtual否则子集也没法重写。
2.如果用子集给父级赋值,子集中override的方法可以重写父级。
3.如果子集中有父级重名方法,则会隐藏子集实现,只展示父级方法(版本控制),或在子集方法中使用new 关键字主动隐藏子集方法
e.g
public class ClassA { public virtual void Eat() { Console.WriteLine("A Eat"); } } public class ClassB:ClassA { public void Eat() { Console.WriteLine("B Eat"); } public void TestB() { } }
如果 赋值 ClassA model=new ClassB();
model 中则没有TestB方法,访问Eat方法时,调用的是ClassA的Eat。如果ClassB中 这样:public void override Eat() 则调用的是ClassB中的方法
当再把model对象转为ClassB时,(ClassB)model 则可以访问TestB方法,Eat方法也是ClassB的了

知识点

Thread.Join方法的使用 线程间的同步

方法说明:调用Join方法的线程,阻塞当前线程,直到调用Join方法的线程执行完毕,再执行当前线程。(可以理解为调用Join方法的线程加塞,先执行完我,再执行别的)
重载版本public bool Thread.Join(Int millisecondsTimeout)
方法说明:先阻塞一段时间(millisecondsTimeout),然后在调用Join方法的线程,阻塞当前线程。
如果在阻塞millisecondsTimeout时间内,调用Join方法的线程完成了,则立即返回true,不再等millisecondsTimeout
如果在阻塞millisecondsTimeout时间内,调用Join方法的线程未完成,则立即返回false
e.g
public class ThreadJoin_Bll { static Thread thread1, thread2; public void Go() { thread1 = new Thread(ThreadProc); thread1.Name = "Thread1"; thread1.Start(); thread2 = new Thread(ThreadProc); thread2.Name = "Thread2"; thread2.Start(); } private static void ThreadProc() { Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name); if (Thread.CurrentThread.Name == "Thread1" && thread2.ThreadState != ThreadState.Unstarted) { Console.WriteLine("\n thread1 State:{0}, thread2 State: {1}",thread1.ThreadState, thread2.ThreadState); // thread2.Join(5000); if (thread2.Join(2000)) Console.WriteLine("Thread2 has termminated."); else Console.WriteLine("The timeout has elapsed and Thread1 will resume."); Console.WriteLine("\ncurrent thread:{0}", Thread.CurrentThread.Name); } if (Thread.CurrentThread.Name == "Thread2") { Thread.Sleep(3000); } Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name); Console.WriteLine("Thread1: {0}", thread1.ThreadState); Console.WriteLine("Thread2: {0}\n", thread2.ThreadState); } }

知识点

ManualResetEvent类的使用 线程间的同步、控制

类说明:构造函数中必须传一个Bool的参数,true:终止,默认不阻塞;false:非终止,默认阻塞。该类控制多个线程的阻塞与执行。
如调用Set方法,会将所有调用waitOne的线程设置为非阻塞。
e.g
public class ManualResetEvent_Bll { ManualResetEvent mre = new ManualResetEvent(false); public void Go() { for (int i = 0; i < 3; i++) { Thread t = new Thread(MyPro); t.Name = "Thread_" + i; t.Start(); } Thread.Sleep(500); Console.WriteLine("\nWhen all three threads have started, press Enter to call Set()" + "\nto release all the threads.\n"); Console.ReadLine(); mre.Set(); Thread.Sleep(500); Console.WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" + "\ndo not block. Press Enter to show this.\n"); Console.ReadLine(); for (int i = 3; i <= 4; i++) { Thread t = new Thread(MyPro); t.Name = "Thread_" + i; t.Start(); } Thread.Sleep(500); Console.WriteLine("\nPress Enter to call Reset(), so that threads once again block" + "\nwhen they call WaitOne().\n"); Console.ReadLine(); mre.Reset(); Thread t5 = new Thread(MyPro); t5.Name = "Thread_5"; t5.Start(); Thread.Sleep(500); Console.WriteLine("\nPress Enter to call Set() and conclude the demo."); Console.ReadLine(); mre.Set(); } void MyPro() { string name = Thread.CurrentThread.Name; Console.WriteLine(name + " start and call waitOne method!"); mre.WaitOne(); Console.WriteLine(name + " ends "); } }

知识点

AutoResetEvent类的使用 线程间的同步、控制

类说明:构造函数中必须传一个Bool的参数,true:终止,默认不阻塞;false:非终止,默认阻塞。该类控制单个线程的阻塞与执行。
如调用Set方法,会将所有调用waitOne的线程中的一个设置为非阻塞;如想释放所有线程,则需多次调用Set方法。
e.g
public class AutoResetEvent_Bll { AutoResetEvent event_1 = new AutoResetEvent(true); AutoResetEvent event_2 = new AutoResetEvent(false); public void Go() { for (int i = 1; i < 4; i++) { Thread t = new Thread(Mypro); t.Name = "Thread_" + i; t.Start(); } Thread.Sleep(250); for (int i = 0; i < 2; i++) { Console.WriteLine("Press Enter to release another thread."); Console.ReadLine(); event_1.Set(); Thread.Sleep(250); } Console.WriteLine("\r\nAll threads are now waiting on AutoResetEvent #2."); for (int i = 0; i < 3; i++) { Console.WriteLine("Press Enter to release a thread."); Console.ReadLine(); event_2.Set(); Thread.Sleep(250); } } private void Mypro() { string name = Thread.CurrentThread.Name; Console.WriteLine("{0} waits on AutoResetEvent #1.", name); event_1.WaitOne(); Console.WriteLine("{0} is released from AutoResetEvent #1.", name); Console.WriteLine("{0} waits on AutoResetEvent #2.", name); event_2.WaitOne(); Console.WriteLine("{0} is released from AutoResetEvent #2.", name); Console.WriteLine("{0} ends.", name); } }

知识点

EventWaitHandle类的使用 线程间的同步、控制

类说明:该类是AutoResetEvent和ManualResetEvent 类的父类,它实现了Set,ReSet方法,用法和两个子类相同,可以考虑多态
构造函数稍不同:EventWaitHandle myH = new EventWaitHandle(false, EventResetMode.ManualReset);

知识点

WaitHandle类的使用 多线程间的同步、控制

类说明:该类是EventWaitHandle类的父类,它实现了静态方法WaitAll、WaitAny、SignalAndWait,虚方法WaitOne
可以看到WaitHandle的一些方法,它就是用来控制多个EventWaitHandl或其子类的多个线程的同步状态的
e.g
public class WaitHandler_Bll { // Define an array with two AutoResetEvent WaitHandles. WaitHandle[] waitHandles = new WaitHandle[] { new AutoResetEvent(false), new AutoResetEvent(false) }; Random r = new Random(); public void Go() { // Queue up two tasks on two different threads; // wait until all tasks are completed. DateTime dt = DateTime.Now; Console.WriteLine("Main thread is waiting for BOTH tasks to complete."); ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]); ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]); WaitHandle.WaitAll(waitHandles); // The time shown below should match the longest task. Console.WriteLine("Both tasks are completed (time waited={0})", (DateTime.Now - dt).TotalMilliseconds); // Queue up two tasks on two different threads; // wait until any tasks are completed. dt = DateTime.Now; Console.WriteLine(); Console.WriteLine("The main thread is waiting for either task to complete."); ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]); ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]); int index = WaitHandle.WaitAny(waitHandles); // The time shown below should match the shortest task. Console.WriteLine("Task {0} finished first (time waited={1}).", index + 1, (DateTime.Now - dt).TotalMilliseconds); } private void DoTask(Object state) { AutoResetEvent are = (AutoResetEvent)state; int time = 1000 * r.Next(2, 10); Console.WriteLine("Performing a task for {0} milliseconds.", time); Thread.Sleep(time); are.Set(); } }

知识点

WaitHandle.WaitOne函数

其中一个版本:public virtual bool WaitOne(int millisecondsTimeout);
说明:先等待millisecondsTimeout秒后,执行WaitOne函数。如果等待millisecondsTimeout期间有调用set方法,则直接返回true;否则,当时间到后,返回false

知识点

WaitHandle.WaitAny函数

其中一个版本:public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout); 注意返回的是int
说明:先等待millisecondsTimeout秒后,执行WaitAny函数。如果等待millisecondsTimeout期间有调用set方法,则直接返回waitHandles中被释放的线程的index,注意下标从0开始;
如果millisecondsTimeout秒后没有释放线程,目前机器上测试会返回258这个数字

知识点

多线程中使用集合

使用集合时,必须lock住集合,否则会报错的
e.g
lock (((ICollection)list).SyncRoot)

知识点

WaitHandle.SignalAndWait 方法的使用

其中一种定义public static bool SignalAndWait (System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn);
说明:向一个 WaitHandle 发出信号并等待另一个。即对第一个参数调用Set方法,第二个参数调用waitone方法
e.g
public class SignalAndWait_Bll { // The EventWaitHandle used to demonstrate the difference // between AutoReset and ManualReset synchronization events. // private static EventWaitHandle ewh; // A counter to make sure all threads are started and // blocked before any are released. A Long is used to show // the use of the 64-bit Interlocked methods. // private static long threadCount = 0; // An AutoReset event that allows the main thread to block // until an exiting thread has decremented the count. // private static EventWaitHandle clearCount = new EventWaitHandle(false, EventResetMode.AutoReset); public void Go() { // Create an AutoReset EventWaitHandle. // ewh = new EventWaitHandle(false, EventResetMode.AutoReset); // Create and start five numbered threads. Use the // ParameterizedThreadStart delegate, so the thread // number can be passed as an argument to the Start // method. for (int i = 0; i <= 4; i++) { Thread t = new Thread( new ParameterizedThreadStart(ThreadProc) ); t.Start(i); } // Wait until all the threads have started and blocked. // When multiple threads use a 64-bit value on a 32-bit // system, you must access the value through the // Interlocked class to guarantee thread safety. // while (Interlocked.Read(ref threadCount) < 5) { Thread.Sleep(500); } // Release one thread each time the user presses ENTER, // until all threads have been released. // while (Interlocked.Read(ref threadCount) > 0) { Console.WriteLine("Press ENTER to release a waiting thread."); Console.ReadLine(); // SignalAndWait signals the EventWaitHandle, which // releases exactly one thread before resetting, // because it was created with AutoReset mode. // SignalAndWait then blocks on clearCount, to // allow the signaled thread to decrement the count // before looping again. // WaitHandle.SignalAndWait(ewh, clearCount); } Console.WriteLine(); // Create a ManualReset EventWaitHandle. // ewh = new EventWaitHandle(false, EventResetMode.ManualReset); // Create and start five more numbered threads. // for (int i = 0; i <= 4; i++) { Thread t = new Thread( new ParameterizedThreadStart(ThreadProc) ); t.Start(i); } // Wait until all the threads have started and blocked. // while (Interlocked.Read(ref threadCount) < 5) { Thread.Sleep(500); } // Because the EventWaitHandle was created with // ManualReset mode, signaling it releases all the // waiting threads. // Console.WriteLine("Press ENTER to release the waiting threads."); Console.ReadLine(); ewh.Set(); } private void ThreadProc(object data) { int index = (int)data; Console.WriteLine("Thread {0} blocks.", data); // Increment the count of blocked threads. Interlocked.Increment(ref threadCount); // Wait on the EventWaitHandle. ewh.WaitOne(); Console.WriteLine("Thread {0} exits.", data); // Decrement the count of blocked threads. Interlocked.Decrement(ref threadCount); // After signaling ewh, the main thread blocks on // clearCount until the signaled thread has // decremented the count. Signal it now. // // clearCount.Set(); } }

知识点

ThreadPool.QueueUserWorkItem方法的使用

其中之一定义:QueueUserWorkItem(WaitCallback, Object)
说明:该静态方法直接使用线程池中可用的线程,第一个参数为回调函数,是WaitCallbak的实例;第二个参数是要传入的参数
e.g
public class Fibonacci_Bll { public void Go() { const int FibonacciCalculations = 5; var doneEvents = new ManualResetEvent[FibonacciCalculations]; var fibArray = new Fibonacci[FibonacciCalculations]; var rand = new Random(); Console.WriteLine($"Launching {FibonacciCalculations} tasks..."); for (int i = 0; i < FibonacciCalculations; i++) { doneEvents[i] = new ManualResetEvent(false); var f = new Fibonacci(rand.Next(20, 40), doneEvents[i]); fibArray[i] = f; ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i); } WaitHandle.WaitAll(doneEvents); Console.WriteLine("All calculations are complete."); for (int i = 0; i < FibonacciCalculations; i++) { Fibonacci f = fibArray[i]; Console.WriteLine($"Fibonacci({f.N}) = {f.FibOfN}"); } } } public class Fibonacci { private ManualResetEvent _doneEvent; public Fibonacci(int n, ManualResetEvent doneEvent) { N = n; _doneEvent = doneEvent; } public int N { get; } public int FibOfN { get; private set; } public void ThreadPoolCallback(Object threadContext) { int threadIndex = (int)threadContext; Console.WriteLine($"Thread {threadIndex} started..."); FibOfN = Calculate(N); Console.WriteLine($"Thread {threadIndex} result calculated..."); _doneEvent.Set(); } public int Calculate(int n) { if (n <= 1) { return n; } return Calculate(n - 1) + Calculate(n - 2); } }

知识点

Interlocked类的使用

类说明:为多个线程共享的变量提供原子操作。
其中较为常用的静态方法
public static int Increment(ref int location);
public static int Decrement(ref int location);
public static int Exchange(ref int location1, int value);
public static long Read(ref long location);
e.g
private static int threadCount = 0; Interlocked.Increment(ref threadCount);

报错:WaitHandles 的数目必须少于或等于 64 个

分析:该问题的发生因为创建了过多的EventWaitHandle或其子类,报错很明显WaitHandles数组的子项最多让创建64个
解决方法:转换下思路,只创建一个EventWaitHandle类,使用一个共享变量,对变量进行原子操作,记录次数
e.g 等待100个线程执行完毕
public class eventWaitHandle_Bll { private static long threadCount = 0; private static long dyCount = 100; private const int lNum = 100; EventWaitHandle myH = new EventWaitHandle(false, EventResetMode.ManualReset); public void Go1() { for (int i = 0; i < lNum; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(MyPro1), i); } myH.WaitOne(); Console.WriteLine(" result number is :{0}", threadCount); } private void MyPro1(object obj) { int a = (int)obj; Console.WriteLine("{0} start", a); Interlocked.Increment(ref threadCount); Console.WriteLine("{0} end.", a); Interlocked.Decrement(ref dyCount); Thread.Sleep(200); if (Interlocked.Read(ref dyCount) == 0) { myH.Set(); } } }

高速

string和字节数组byte[]的转换
string转byte[]:
byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str );
byte[]转string:
string str = System.Text.Encoding.Default.GetString ( byteArray );
string转ASCII byte[]:
byte[] byteArray = System.Text.Encoding.ASCII.GetBytes ( str );
ASCII byte[]转string:
string str = System.Text.Encoding.ASCII.GetString ( byteArray );