在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 一.通过委托的方式 委托中的Invoke方法完成一个委托方法的封送,在Invoke封送的方法被执行完毕前,Invoke方法不会返回,从而调用者线程将被阻塞。委托中的BeginInvoke方法是从ThreadPool取出一个线程来执行这个方法,以获得异步执行效果的。 public delegate int AddDelegate(int a, int b); //定义一个委托对象 static void Main(string[] args) { Console.WriteLine("start"); AddDelegate d1 = Add; //异步回调方法,异步方法执行完可以选择执行这个方法 AsyncCallback cab = t => { //Console.WriteLine(d1.EndInvoke(t)); Console.WriteLine(t.AsyncState); //可以获取传递过来的参数 Console.WriteLine(t.IsCompleted); }; IAsyncResult ar = d1.BeginInvoke(5,2,cab,12); //前两个参数为引用方法传递的参数,cab为上面的回调方法,12为回调方法中的参数,执行BeginInvoke会返回一个IAsyncResult对象 Thread.Sleep(2000); int result = d1.EndInvoke(ar); //该方法返回委方法中的真正返回值,该方法会阻塞主线程一直到异步执行完,EndInvoke只能被执行一次 Console.WriteLine("结果:"+result); } public static int Add(int a,int b) { return a + b; } 二.通过Thread类 C#中的Thread类主要提供四个构造方法,ThreadStart是一个无参的委托,意味着我们能传递一个无参的方法进去。ParameterizedThreadStart是一个只有一个参数,参数类型为object的委托,我们可以传一个一个参数,参数类型为object的类型进去 static void Main(string[] args) { //ThreadStart start1 = AddNoParms; //Thread thread1 = new Thread(start1); Thread thread1 = new Thread(AddNoParms); //简化写法,直接传递与委托方法签名对应的方法 Thread thread2 = new Thread(AddHasParms); //有参的形式 thread1.Start();//开启这个线程 thread2.Start("thread2"); //开启有参的Thread线程 thread1.Name = "thread1"; //获取或设置线程的名称。 thread1.IsBackground = true; //获取或设置一个值,该值指示某个线程是否为后台线程。 Thread.Sleep(2000); //让线程暂停一段时间。 thread1.Abort(); //销毁线程 Console.WriteLine(thread1.IsAlive); //获取线程状态 //获取异步回调的返回值 int returndata = 0; //声明一个变量用来接收异步方法执行的返回值 ThreadStart threadstart = new ThreadStart (() =>{ returndata = Add(1, 2); AddNoParms(); }); Thread thread3 = new Thread(threadstart); thread3.Start(); Console.WriteLine(returndata); } public static void AddHasParms(object str) { Console.WriteLine(str); } public static void AddNoParms() { Console.WriteLine(Thread.CurrentThread.ManagedThreadId); Console.WriteLine("add"); } public static int Add(int a,int b) { return a + b; } Thread类中还提供了许多属性和方法供我们使用 //属性 IsAlive //获取一个值,该值指示当前线程的执行状态。 IsBackground //获取或设置一个值,该值指示某个线程是否为后台线程。前台进程跟后台进程的区别:程序关闭时,后台线程直接关闭,但前台线程会执行完后关闭。通过Thread类新建线程默认为前台线程。其他方式创建的都是后台线程。 IsThreadPoolThread //获取一个值,该值指示线程是否属于托管线程池。 Priority //获取或设置一个值,该值指示线程的调度优先级。 //方法 Abort //在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。 Join //阻塞调用线程,直到某个线程终止为止。此方法有不同的重载形式 ResetAbort //取消为当前线程请求的 Abort。 三.ThreadPool ThreadPool类会在线程的托管池中重用已有的线程,一个应用程序最多只能有一个线程池,可以通过QueueUserWorkItem方法将工作函数排入进程池。QueueUserWorkItem有两个构造函数,WaitCallback是一个只有一个参数,参数类型为object的委托,我们可以传一个参数,参数类型为object的对象进行实例化 static void Main(string[] args) { 四.Task static void Main(string[] args) { //方式一 无返回值时 Task task1 = new Task(AddHasParms, "helloworld"); task1.Start(); Task.WaitAll(task1); //等待所有任务结束 //有返回值时 Task<int> task2 = new Task<int>(Add, "obj"); task2.Start(); Console.WriteLine(task2.Result); //打印返回值 //方式二 通过Run方法创建 无返回值 Task.Run(() => AddHasParms("hello")); //无返回值时 Task<int> task3 = Task.Run(() => Add("obj")); Console.WriteLine(task3.Result); //方式三 无返回值时 Task.Factory.StartNew(() => AddHasParms("helloworld")); Task.WaitAll(); //有返回值时 var task4=Task.Factory.StartNew(() => Add("obj")); Console.WriteLine(task4.Result); } public static void AddHasParms(object str) { Console.WriteLine(Thread.CurrentThread.ManagedThreadId); Console.WriteLine(str); } public static int Add(object a) { return 1; }
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论