• c# 多线程学习(一)


    今天回顾了一下c#的多线程机制。平时写程序很少写多线程的,因此我也感觉以前的程序都很低级。

    没使用过多线程的时候,对它的机制很好奇。它究竟是怎么执行的呢?从什么地方冒出另外一个线程的? 其实我现在认为,就是另开了一个线程,执行某个函数。注意重点,“执行某个函数”。

    目前我知道有两种方式实现多线程编程: thread类 和 委托线程

    一、使用thread 类

      

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading;
     6 
     7 namespace ConsoleTest
     8 {
     9     class Program
    10     {
    11         public static void TaskThread()
    12         {
    13             Console.WriteLine("thread running.");
    14             Thread.Sleep(5000);
    15             Console.WriteLine("thread finish.");
    16         }
    17 
    18         public static void Main(string[] args)
    19         {
    20             Thread thread = new Thread(TaskThread);
    21             thread.IsBackground = true;
    22             thread.Start();
    23             Console.WriteLine("main finish");
    24         }
    25     }
    26 }

    既然是初学,自然是举很简单的例子了。 thread的构造函数里面是一个void类型无参数的函数。注意到里面有一行代码:

    1  thread.IsBackground = true;

    thread 创建的线程默认是前台线程,就是说,只要有一个线程没有执行完,程序就不会退出。但是把 IsBackground 设置为 true 之后,只要其他的前台线程结束了,不管后台线程是否完毕,进程都会退出。

    可以在线程里加入参数。

    View Code
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading;
     6 
     7 namespace ConsoleTest
     8 {
     9 
    10     class Parameter
    11     {
    12        public  string words ;
    13     }
    14 
    15     class Program
    16     {
    17         public static void TaskThread(object o)
    18         {
    19             Console.WriteLine("thread running.");
    20             Thread.Sleep(1000);
    21             Console.WriteLine(((Parameter)o).words);
    22             Console.WriteLine("thread finish.");
    23         }
    24 
    25         public static void Main(string[] args)
    26         {
    27             Thread thread = new Thread(TaskThread);
    28             thread.Start(new Parameter() { words = "lianjx should study hard and marry 00 in the near feature." });
    29             Console.WriteLine("main finish");
    30             Console.ReadKey();
    31         }
    32     }
    33 }

    thread有一些方法可以控制线程,如Abort(),Join(),Resume().
    还可以用线程池,线程池里的线程都是后台线程

    View Code
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading;
     6 
     7 namespace ConsoleTest
     8 {
     9 
    10     class Parameter
    11     {
    12        public  string words ;
    13     }
    14 
    15     class Program
    16     {
    17         public static void TaskThread(object o)
    18         {
    19             Console.WriteLine("thread running.");
    20             Thread.Sleep(1000);
    21             Console.WriteLine("thread finish.");
    22         }
    23 
    24         public static void Main(string[] args)
    25         {
    26             for (int i = 0; i < 5; i++)
    27             {
    28                 ThreadPool.QueueUserWorkItem(TaskThread);
    29             }
    30 
    31             Console.ReadKey();
    32         }
    33     }

    二、创建线程的另一种方式是委托。

    View Code
     1 class Program
     2     {
     3         public static float newTask(int ms)
     4         {
     5             Console.WriteLine("new task begins. test thread");
     6             Thread.Sleep(4000);
     7 
     8             Console.WriteLine("thread {0} finish",ms);
     9 
    10             return ms;
    11         }
    12 
    13         public delegate float NewTaskDelegate(int ms);
    14 
    15         public static void Main(string[] args)
    16         {
    17             NewTaskDelegate task1 = newTask;
    18             NewTaskDelegate task2 = newTask;
    19 
    20             IAsyncResult result1 = task1.BeginInvoke(1, null, null);
    21             IAsyncResult result2 = task2.BeginInvoke(2, null, null);
    22 
    23 
    24             // 等到两个线程都执行完毕之后才结束循环
    25             int finish = 0;
    26             while (true)
    27             {
    28                 if (result1.IsCompleted)
    29                     finish = finish | 1;
    30                 if (result2.IsCompleted)
    31                     finish = finish | 2;
    32                 if (finish == 3)
    33                     break;
    34             }
    35 
    36             Console.WriteLine("Now get result...");
    37             Console.WriteLine("{0}\t{1}",task1.EndInvoke(result1),task2.EndInvoke(result2));
    38             Console.ReadKey();
    39         }
    40     }

    关键是委托函数的BeginInvoke 和EndInvoke 。 BeginInvoke()的最后两个参数是回调用的,委托建立线程有很多技巧和这两个参数有关,这里不多说。
    一旦执行BeginInvoke,就在后台开了一个线程,主函数Main执行到EndInvoke(),如果线程没有执行完毕,那么主函数会一直阻塞等待。所以在EndInvoke之前,通过IAsyncResult 携带的线程信息来确定是否执行完毕,以免程序陷入假死的状态。

  • 相关阅读:
    瀑布流布局——JS+绝对定位
    浏览器事件的思考
    css的hack详解
    主流浏览器的Hack写法
    [HTML&CSS] 未知高度多行文本垂直居中
    HTML标签的默认样式列表
    推荐的 CSS 书写顺序
    高效整洁CSS代码原则 (上)
    高效整洁CSS代码原则 (下)
    Xcode升级导致插件失效的解决办法
  • 原文地址:https://www.cnblogs.com/sylvanas2012/p/2610591.html
Copyright © 2020-2023  润新知