前言

学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";
}