`

以ThreadStart方式实现多线程(转载)

 
阅读更多
以ThreadStart方式实现多线程(转载)
3.1 使用ThreadStart委托
这 里先以一个例子体现一下多线程带来的好处,首先在Message类中建立一个方法ShowMessage(),里面显示了当前运行线程的Id,并使用 Thread.Sleep(int ) 方法模拟部分工作。在main()中通过ThreadStart委托绑定Message对象的ShowMessage()方法,然后通过 Thread.Start()执行异步方法。
1       public class Message
2       {
3           public void ShowMessage()
4           {
5               string message = string.Format("Async threadId is :{0}",
6                                               Thread.CurrentThread.ManagedThreadId);
7               Console.WriteLine(message);
8  
9               for (int n = 0; n < 10; n++)
10               {
11                   Thread.Sleep(300);  
12                   Console.WriteLine("The number is:" + n.ToString());
13               }
14           }
15       }
16  
17       class Program
18       {
19           static void Main(string[] args)
20           {
21               Console.WriteLine("Main threadId is:"+
22                                 Thread.CurrentThread.ManagedThreadId);
23               Message message=new Message();
24               Thread thread = new Thread(new ThreadStart(message.ShowMessage));
25               thread.Start();
26               Console.WriteLine("Do something ..........!");
27               Console.WriteLine("Main thread working is complete!");
28              
29           }
30       }
请注意运行结果,在调用Thread.Start()方法后,系统以异步方式运行Message.ShowMessage(),而主线程的操作是继续执行的,在Message.ShowMessage()完成前,主线程已完成所有的操作。
3.2 使用ParameterizedThreadStart委托
ParameterizedThreadStart 委托与ThreadStart委托非常相似,但ParameterizedThreadStart委托是面向带参数方法的。注意 ParameterizedThreadStart 对应方法的参数为object,此参数可以为一个值对象,也可以为一个自定义对象。
1     public class Person
2     {
3         public string Name
4         {
5             get;
6             set;
7         }
8         public int Age
9         {
10             get;
11             set;
12         }
13     }
14
15     public class Message
16     {
17         public void ShowMessage(object person)
18         {
19             if (person != null)
20             {
21                 Person _person = (Person)person;
22                 string message = string.Format("\n{0}'s age is {1}!\nAsync threadId is:{2}",
23                     _person.Name,_person.Age,Thread.CurrentThread.ManagedThreadId);
24                 Console.WriteLine(message);
25             }
26             for (int n = 0; n < 10; n++)
27             {
28                 Thread.Sleep(300);  
29                 Console.WriteLine("The number is:" + n.ToString());
30             }
31         }
32     }
33
34     class Program
35     {
36         static void Main(string[] args)
37         {    
38             Console.WriteLine("Main threadId is:"+Thread.CurrentThread.ManagedThreadId);
39            
40             Message message=new Message();
41             //绑定带参数的异步方法
42             Thread thread = new Thread(new ParameterizedThreadStart(message.ShowMessage));
43             Person person = new Person();
44             person.Name = "Jack";
45             person.Age = 21;
46             thread.Start(person);  //启动异步线程
47            
48             Console.WriteLine("Do something ..........!");
49             Console.WriteLine("Main thread working is complete!");
50             
51         }
52     }

3.3 前台线程与后台线程
注意以上两个例子都没有使用Console.ReadKey(),但系统依然会等待异步线程完成后才会结束。这是因为使用Thread.Start()启动的线程默认为前台线程,而系统必须等待所有前台线程运行结束后,应用程序域才会自动卸载。
在第二节曾经介绍过线程Thread有一个属性IsBackground,通过把此属性设置为true,就可以把线程设置为后台线程!这时应用程序域将在主线程完成时就被卸载,而不会等待异步线程的运行。

3.4 挂起线程
为了等待其他后台线程完成后再结束主线程,就可以使用Thread.Sleep()方法。
1     public class Message
2     {
3         public void ShowMessage()
4         {
5             string message = string.Format("\nAsync threadId is:{0}",
6                                            Thread.CurrentThread.ManagedThreadId);
7             Console.WriteLine(message);
8             for (int n = 0; n < 10; n++)
9             {
10                 Thread.Sleep(300);
11                 Console.WriteLine("The number is:" + n.ToString());
12             }
13         }
14     }
15
16     class Program
17     {
18         static void Main(string[] args)
19         {    
20             Console.WriteLine("Main threadId is:"+
21                               Thread.CurrentThread.ManagedThreadId);
22            
23             Message message=new Message();
24             Thread thread = new Thread(new ThreadStart(message.ShowMessage));
25             thread.IsBackground = true;
26             thread.Start();
27            
28             Console.WriteLine("Do something ..........!");
29             Console.WriteLine("Main thread working is complete!");
30             Console.WriteLine("Main thread sleep!");
31             Thread.Sleep(5000);
32         }
33     }
运行结果如下,此时应用程序域将在主线程运行5秒后自动结束
但 系统无法预知异步线程需要运行的时间,所以用通过Thread.Sleep(int)阻塞主线程并不是一个好的解决方法。有见及此,.NET专门为等待异 步线程完成开发了另一个方法thread.Join()。把上面例子中的最后一行Thread.Sleep(5000)修改为 thread.Join() 就能保证主线程在异步线程thread运行结束后才会终止。

3.5 Suspend 与 Resume (慎用)
Thread.Suspend() 与 Thread.Resume()是在Framework1.0 就已经存在的老方法了,它们分别可以挂起、恢复线程。但在Framework2.0中就已经明确排斥这两个方法。这是因为一旦某个线程占用了已有的资源, 再使用Suspend()使线程长期处于挂起状态,当在其他线程调用这些资源的时候就会引起死锁!所以在没有必要的情况下应该避免使用这两个方法。

3.6 终止线程
若想终止正在运行的线程,可以使用Abort()方法。在使用Abort()的时候,将引发一个特殊异常 ThreadAbortException 。
若想在线程终止前恢复线程的执行,可以在捕获异常后 ,在catch(ThreadAbortException ex){...} 中调用Thread.ResetAbort()取消终止。
而使用Thread.Join()可以保证应用程序域等待异步线程结束后才终止运行。
1          static void Main(string[] args)
2          {
3              Console.WriteLine("Main threadId is:" +
4                                Thread.CurrentThread.ManagedThreadId);

6              Thread thread = new Thread(new ThreadStart(AsyncThread));
7              thread.IsBackground = true;
8              thread.Start();
9              thread.Join();
10 
11          }    
12         
13          //以异步方式调用
14          static void AsyncThread()
15          {
16              try
17              {
18                  string message = string.Format("\nAsync threadId is:{0}",
19                     Thread.CurrentThread.ManagedThreadId);
20                  Console.WriteLine(message);
21 
22                  for (int n = 0; n < 10; n++)
23                  {
24                      //当n等于4时,终止线程
25                      if (n >= 4)
26                      {
27                          Thread.CurrentThread.Abort(n);
28                      }
29                      Thread.Sleep(300);
30                      Console.WriteLine("The number is:" + n.ToString());
31                  }
32              }
33              catch (ThreadAbortException ex)
34              {
35                  //输出终止线程时n的值
36                  if (ex.ExceptionState != null)
37                      Console.WriteLine(string.Format("Thread abort when the number is: {0}!",
38                                                       ex.ExceptionState.ToString()));
39                
40                  //取消终止,继续执行线程
41                  Thread.ResetAbort();
42                  Console.WriteLine("Thread ResetAbort!");
43              }
44 
45              //线程结束
46              Console.WriteLine("Thread Close!");
47          }
分享到:
评论

相关推荐

    Thread实现多线程

    继承Thread类: 1必须重写run 方法:里面放置的实际的线程体 2 启动线程: 3创建Thread对象 4调用Thread对象的start 方法启动线程

    Java有两种实现多线程的方式:通过Runnable接口、通过Thread直接实现,请掌握这两种实现方式,并编写示例程序。

    ### Java中的两种多线程实现方式 在Java中,实现多线程的两种主要方式分别是:**通过继承`Thread`类** 和 **实现`Runnable`接口**。下面将详细介绍这两种方式,并提供相应的示例程序。 #### 一、通过继承`Thread`...

    多线程两种实现方式Java

    总结,理解并熟练掌握Java中的多线程实现方式是提升程序性能和编写高效并发代码的基础。无论你是通过继承`Thread`还是实现`Runnable`,都需要对线程同步和通信有深入的理解,以便在实际项目中解决并发问题。通过实践...

    QT多线程moveToThread使用方式

    `moveToThread`函数是QT多线程编程中的一个重要方法,它允许我们将一个对象移动到指定的QThread对象中,从而使该对象的工作在新的线程上下文中执行。 首先,理解多线程的基本概念至关重要。在计算机科学中,线程是...

    C#实现多线程下载文件

    在进行多线程下载时,我们创建多个线程,每个线程负责下载文件的一部分,从而实现并行下载,加快速度。 C#中可以使用`System.Threading.Thread`类创建新线程,但考虑到线程的管理和资源消耗,更推荐使用线程池(`...

    PB多线程实现

    PB,全称PowerBuilder,是一种历史悠久的面向对象...总的来说,PB系列(尤其是PB12.5和PB.NET)提供了多种多线程实现方式,适应了不同开发需求。理解并掌握这些技术,能帮助开发者构建更加高效、响应迅速的PB应用程序。

    .Net下多线程的四种编程实现方式详解

    详细讲解了多线程的四种实现方式(Thread、线程池、Task、委托),以及各种实现方式的优缺点。相信对于想学习多线程的朋友是个不错的选择。

    VB中实现多线程

    在VB(Visual Basic)编程环境中,实现多线程是一项重要的技术,它允许程序同时执行多个独立的任务,提高程序的响应速度和效率。VB虽然没有内置的多线程支持,但可以通过使用API函数或者.NET Framework提供的System....

    VB6实现多线程数据库大数据查询

    多线程在.net中实现是非常容易的。 VB6本身无法实现多线程编程,但是通过第三方控件,也可以很完美的实现多线程。 本例实现的是在主界面开一个新的线程在后台完成数据查询并根据提供的每页显示的数据行数计算出总...

    vb实现多线程实例代码

    - **线程方法**:每个线程都有一个执行的方法,通常称为`ThreadStart`委托类型的方法。你可以将要在线程上运行的代码封装在这个方法中。 3. **线程同步与互斥** - **Mutex** 和 **Semaphore**:这些类用于控制对...

    stm32单片机多线程实例

    在STM32上实现多线程,通常会借助实时操作系统(RTOS)如RT-Thread。 RT-Thread是一个轻量级、开源的实时操作系统,它为STM32等微控制器提供了强大的多任务管理能力。通过创建和调度线程,RT-Thread使得开发者可以...

    JAVA100例之实例60 继承Thread实现多线程

    总之,通过继承`Thread`类创建多线程是Java中一种常见的实现方式,但也有其他方式,比如实现`Runnable`接口或使用`ExecutorService`。每种方法都有其适用场景,开发者应根据需求选择合适的方式。在实际编程中,了解...

    VB实现真正的稳定多线程(含源码)

    通过分析提供的压缩包文件名称`vbThreadNew`,我们可以猜测这是一个包含VB多线程实现的源代码示例,可能提供了一种新的线程创建和管理方式,以提高稳定性和性能。学习和研究这个源码,可以帮助我们更好地理解和实践...

    实现Runnable接口创建多线程.docx

    在Java编程语言中,创建线程有两种主要方式:继承`Thread`类和实现`Runnable`接口。由于Java的单继承特性,当一个类需要继承其他类时,就不能再直接继承`Thread`,这时实现`Runnable`接口就成为创建线程的优选方案。...

    C#多线程实现定时器

    Thread rd = new Thread(new ThreadStart(start)); rd.IsBackground = true; count = 0; rd.Start(); } private void start() { DateTime dt_tem = DateTime.Now; interval_date interval = new ...

    在PB中实现 多线程的例子

    在PowerBuilder(PB)中实现多线程是一个高级主题,对于提升应用程序的性能和响应性至关重要。PowerBuilder是一个强大的客户端/服务器(client-server)开发工具,尤其适合于构建数据库应用。在PB中引入多线程可以让...

    VB.Net-C#多线程Thread-代理委托delegate编程

    最近收集的VB.Net-C#多线程Thread-代理委托delegate编程。文章列表: c#.net多线程同步.txt C#WebBrowser页面与WinForm交互技巧一.txt C#多线程编程-多细全.txt C#多线程编程简单实例.txt C#多线程窗体控件安全访问....

    winform 实现多线程登录

    本文将深入探讨如何在WinForm应用程序中实现多线程登录功能,同时结合进度条和图片旋转效果,为用户提供更好的交互体验。 首先,让我们理解多线程的概念。在单线程程序中,所有操作都在同一个线程上执行,这可能...

    多线程编程示例

    本文将深入探讨多线程编程的基础知识,以帮助初学者快速入门。 首先,我们需要理解什么是多线程。多线程是指在一个进程中同时执行多个独立的执行线程。在单核CPU系统中,操作系统通过时间片轮转的方式在不同线程...

    QT多线程的实现方式:QThread run优雅的创建与退出QT多线程

    QT提供了多种实现多线程的方式,其中QThread类是最常用的一种。本文将详细讲解如何在QT中使用QThread来优雅地创建和退出多线程。 一、QThread简介 QThread是QT中的一个类,用于提供线程功能。与标准C++库中的std::...

Global site tag (gtag.js) - Google Analytics