一、Thread进程;;主要是先声明 ,声明的时候可以根据需要传递参数或者不传递,以及指定栈大小;生成的进程,要start后才启动,启动后,可以查询状态(ThreadState 属性)
通过一个委托进行实例化一个函数public delegate void ParameterizedThreadStart(object obj);
Thread threadName1 = new Thread(new ParameterizedThreadStart(myOneArgFun));
MyArg arg = new MyArg("name",20);
threadName1.IsBackground = false;//是否后台进程
threadName1.Start(arg); //启动了一个带参数的进程
//threadName1.Join();//等待进程,不会再继续
Console.WriteLine("stop main");
//Console.ReadLine();
//threadName1.Join();//等待进程,不会再继续执行后面的内容
//threadName1.Abort();//终止进程
//Thread treadName = Thread.CurrentThread; 可以在子进程中获取自己的进程名字,方便进行操作
//threadName1.Suspend();
//threadName1.IsBackground = true;//是否后台进程
//Thread threadName2 = new Thread(new ThreadStart(targNoArg));//定义一个无参数的进程
//Thread threadName3 = new Thread(new ParameterizedThreadStart(myOneArgFun),10000);//定义一个有一个参数的进程 并指定栈的大小
//Thread threadName4 = new Thread(new ThreadStart(targNoArg),10000);//定义一个无参数的进程并指定栈的大小
//m默认的参数类型都是 obj格式,可以自己定义,然后自己转换
//threadName2.Start();
也可以使用简单方法,直接定义一个参数或0参数的,根据你的函数自动调用
Thread threadname4 = new Thread(myOneArgFun);
Thread threadname5 = new Thread(targNoArg);
除了上述方法,传递参数的时候,还可以通过先实例化一个有属性有方法(没有参数)的类,然后定义线程的时候,使用该实例的方法,就可以直接使用该类中的其他属性
Thread threadname6 = new Thread(new ThreadStart(arg.printname));
public class MyArg:Object {
public MyArg(string name, int age)
{
this.name = name;
this.age = age;
}
string name { get; set; }
int age { get; set; }
public void printname() {
Thread.Sleep(1000);
Console.WriteLine(name);
Console.WriteLine(age);
Thread.Sleep(2000);
}
}
2)线程池 暂时还没有使用,这里是拷贝的,后面有机会再去研究;
ThreadPool类维护一个线程的列表,提供给用户以执行不同的小任务,减少频繁创建线程的开销。ThreadPool的使用比较简单,只需调用ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallback类型的委托,线程池即从池中选择一个线程执行该任务。
链接:https://www.jianshu.com/p/36a65838fe46
public static void Main()
{
for (int i = 0; i < 5; ++i)
ThreadPool.QueueUserWorkItem(DoWork);
Console.ReadKey();
}
public static void DoWork(Object o)
{
for (int i = 0; i < 3; i++)
Console.WriteLine("loop:{0}, thread id: {1}", i, Thread.CurrentThread.ManagedThreadId);
}
3)TASK这个是比较重要的,相比于Thread类,Task类为控制线程提供了更大的灵活性。Task类可以获取线程的返回值,也可以定义连续的任务——在一个任务结束结束后开启下一个任务,还可以在层次结构中安排任务,在父任务中可以创建子任务,这样就创建了一种依赖关系,如果父任务被取消,子任务也随之取消。Task类默认使用线程池中的线程,如果该任务需长期运行,应使用TaskCreationOptions.LongRunning属性告诉任务管理器创建一个新的线程,而不是使用线程池中的线程。
最简单的的任务执行,使用的lambda表达式;
Task.Run(() => {
while (true)
{
Console.WriteLine("loop");
Thread.Sleep(100);
}
});
Task t2 = new Task(() => {
while (true)
{
Console.WriteLine("loop222");
Thread.Sleep(100);
}
});
t2.Start();
Thread.Sleep(1000);
Console.WriteLine("stop main");
4)多线程会涉及到资源冲突,lock有时会需要到;关键设置为 readonly 然后通过lock锁定。
readonly object locker = new object();
public void fun() {
lock (locker)
{
}
}