前言 学java的时候没记,学c#的时候赶紧补上
进程和线程 进程是进程是操作系统资源分配 的基本单位。每个进程都有独立的代码和数据空间(程序上下文) 线程是处理器任务调度和执行 的基本单位,同一进程的线程共享本进程的地址空间和资源,而每个线程都有自己独立的运行栈和程序计数器(PC)
进程管理(Process类) 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 //获取本机所以进程 Process[] processes = Process.GetProcesses(); //获取本机指定名称的进程 Process[] myProcesses1 = Process.GetProcessesByName("MyExeFile"); //不要带扩展名 //打开进程 string startinfo = textbox.Text; Process p = new Process();//p.Id p.ProcessName try { Process.Start(startinfo); } catch (Exception) { MessageBox.Show("error"); } //杀死进程 Process my = Process.GetProcessById(data.id); my.Kill(); //对于有界面的应用程序,一般使用CloseMainWindow方法来关闭它,而不是用Kill方法来关闭,如果CloseMainWindow方法失败,可以再使用Kill方法终止进程。 if (! process1.HasExited)//HasExited属性用于判断启动的进程是否已停止运行 { my.CloseMainWindow(); }
线程管理(Thread类) 进程创建一个默认的线程,该线程称为主线程 。或者说,主线程用于执行Main方法中的代码,当Main方法返回时,主线程也自动终止。在一个进程中,除了主线程之外的其他线程都称为辅助线程 。 一个线程要么是前台线程 ,要么是后台线程 。两者的区别是:后台线程不会影响进程的终止,而前台线程则会影响进程的终止。如main方法就是一个前台线程,用Thread对象创建的线程默认都是前台线程
1 2 3 4 5 Thread t1 = new Thread(F); t1.IsBackground = true;//如果在后台执行则为true;否则为false。 t1.Start(); t1.Sleep(1000)//休眠线程
编写多线程并发程序 并发执行是指多个任务(线程或进程)在一段时间内交替进行,并且给用户的感觉是多个线程同时执行。通过并发执行,可以提高系统的性能和响应能力,充分利用CPU资源。
编写多线程并发程序时,需要解决多线程执行过程中的资源同步问题 (死锁和争用情况)
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 Stopwatch mayylu = new Stopwatch();//测量运行时间 for (int i = 0; i < n; i++) { strip = strqz + (int.Parse(strqsz) + i).ToString(); mayylu.Start(); Thread t = new Thread(scan); t.Start(strip);//传参 threads.Add(t); } public void scan(object ip) { string hostname; Stopwatch watch = new Stopwatch(); watch.Start(); IPHostEntry host = Dns.GetHostEntry(ip.ToString()); try { hostname = host.HostName.ToString(); } catch (Exception) { hostname = "不能获取"; } watch.Stop(); long ms = watch.ElapsedMilliseconds; //委托给控件的创建线程(主线程)来完成 tb.Dispatcher.Invoke(() => tb.Text += "扫描地址: " + ip + " 扫描时间: " + ms + "毫秒" + " 主机DNS名称:" + hostname + "\n"); lock (obj) { num++; }//保护数据在某个时刻内只有一个线程可以操作该数据,直至操作完毕才允许其他线程进行操作 count = threads.Count; if (num == count) { mayylu.Stop(); tb.Dispatcher.Invoke(() => tb.Text += "总时间:" + mayylu.ElapsedMilliseconds + "毫秒"); }
异步编程 委托 1 2 3 4 5 6 7 8 9 10 11 12 Func<int, int> func1 = (int x) => x - 2;//lambda表达式简写函数F3,语句块只有一行可直接写 Func<int, string, string> func2 = (int x, string s) => { string str; if (s.Length > x) return str = "s.Length>x"; else return str = "s.Length<=x"; }; Func<int, int, bool> func3 = (x, y) => x == y;//Lambda 表达式的参数可以不写类型 Console.WriteLine(func1(x)); Console.WriteLine(func2(x,"1234")); Console.WriteLine(func3(x,10));
基于任务的异步编程 在基于任务的编程模型中,并行和异步都是通过任务来实现的。在多任务编程中,要么异步执行一个或多个任务,要么并行执行多个任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 static void Main(){ var task = Task.Run(() =>{//运行Task.Run时会开启一个新线程 return GetName(); }); var name = task.GetAwaiter().GetResult(); Console.WriteLine("主线程执行完毕"); Console.ReadLine(); } static string GetName(){ Console.WriteLine("另外一个线程在获取名称"); Thread.Sleep(2000); return "Jesse"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 async Task Main()//带有async修饰符的事件处理程序称为异步事件处理程序 { var name =GetName();//不会等待结果 Console.WriteLine("主线程执行完毕"); //包含await运算符的代码必须放在异步方法的内部 Console.WriteLine("等待返回结果"+await name);//等待Task执行完毕 } //如果方法没有返回值,则用async和Task共同签名。 //如果方法有返回值,则用async和Task<>共同签名。 static async Task<string> GetName() { Console.WriteLine(""); await Task.Delay(2000); return "mayylu"; }