zoukankan      html  css  js  c++  java
  • C#多线程之基础篇1

      在多线程这一系列文章中,我们将讲述C#语言中多线程的相关知识,在多线程(基础篇)中我们将学习以下知识点:

    • 创建线程
    • 中止线程
    • 线程等待
    • 终止线程
    • 确定线程的状态
    • 线程优先级
    • 前台线程和后台线程
    • 向线程传递参数
    • 使用C#的lock关键字锁定线程
    • 使用Monitor锁定线程
    • 处理异常

    一、创建线程

      在整个系列文章中,我们主要使用Visual Studio 2015作为线程编程的主要工具。在C#语言中创建、使用线程只需要按以下步骤编写即可:

    1、启动Visual Studio 2016,新建一个控制台应用程序。

    2、确保该控制台程序使用.NET Framework 4.6或以上版本。然而在该篇中的所有示例使用较低版本可以正常工作。

    3、双击打开该控制台应用程序中的“Program.cs”文件,在其中编写如下代码:

     1 using System;
     2 using System.Threading;
     3 using static System.Console;
     4 
     5 namespace Recipe01
     6 {
     7     class Program
     8     {
     9         static void PrintNumbers()
    10         {
    11             WriteLine("Starting...");
    12             for (int i = 1; i < 10; i++)
    13             {
    14                 WriteLine(i);
    15             }
    16         }
    17 
    18         static void Main(string[] args)
    19         {
    20             Thread t = new Thread(PrintNumbers);
    21             t.Start();
    22             PrintNumbers();
    23         }
    24     }
    25 }

    4、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

      在第2行代码处,我们导入了System.Threading命名空间,该命名空间包含了我们编写多线程程序所需要的所有类型。

      在第3行代码处,我们使用了C# 6.0的using static特性,使用了该特性之后,在代码中允许我们在使用System.Console类型的静态方法的时候不需要指定其类型名。

      在第9~16行代码处,我们定义了一个名为“PrintNumbers”的方法,该方法将在“Main”方法和线程中进行调用。

      在第20行代码处,我们创建了一个线程来运行“PrintNumbers”方法,当我们初始化一个线程时,一个“ThreadStart”或“ParameterizedThreadStart”委托的实例被传递给线程的构造方法。

      在第21行代码处,我们启动线程。

      在第22行代码处,我们在“Main”方法中调用“PrintNumbers”方法。

    二、中止线程

       在这一节,我们将让线程等待一些时间,在等待的这段时间内,该线程不会消耗操作系统的资源。编写步骤如下:

    1、使用Visual Studio 2015创建一个新的控制台应用程序。

    2、双击打开“Program.cs”文件,编写代码如下所示:

     1 using System;
     2 using System.Threading;
     3 using static System.Console;
     4 using static System.Threading.Thread;
     5 
     6 namespace Recipe02
     7 {
     8     class Program
     9     {
    10         static void PrintNumbers()
    11         {
    12             WriteLine("Starting...");
    13 
    14             for(int i = 1; i < 10; i++)
    15             {
    16                 WriteLine(i);
    17             }
    18         }
    19 
    20         static void PrintNumbersWithDelay()
    21         {
    22             WriteLine("Starting...");
    23 
    24             for(int i = 1; i < 10; i++)
    25             {
    26                 Sleep(TimeSpan.FromSeconds(2));
    27                 WriteLine(i);
    28             }
    29         }
    30 
    31         static void Main(string[] args)
    32         {
    33             Thread t = new Thread(PrintNumbersWithDelay);
    34             t.Start();
    35             PrintNumbers();
    36         }
    37     }
    38 }

    3、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

      在第20~29行代码处,我们定义了一个新的方法“PrintNumbersWithDelay”,该方法将在我们新建的线程中运行。需要注意的是在第26行代码处,我们使用了“Thread”类的静态方法“Sleep”,该方法使得每次循环都会等待2秒钟执行。

      在第33行代码处,我们创建一个新的线程来运行“PrintNumbersWithDelay”方法。

    三、线程等待

       在这一节中,我们将讲述如何在一个线程执行完毕后,再执行剩余的代码,要完成这个工作,我们不能使用Thread.Sleep方法,因为我们不知道另一个线程精确的执行时间。要使一个线程等待另一个线程执行完毕后再进行其他工作,只需要按下列步骤编写代码即可:

    1、使用Visual Studio 2015创建一个新的控制台应用程序。

    2、双击打开“Program.cs”文件,编写如下代码:

     1 using System;
     2 using System.Threading;
     3 using static System.Console;
     4 using static System.Threading.Thread;
     5 
     6 namespace Recipe03
     7 {
     8     class Program
     9     {
    10         static void PrintNumbersWithDelay()
    11         {
    12             WriteLine("Starting...");
    13 
    14             for(int i = 1; i < 10; i++)
    15             {
    16                 Sleep(TimeSpan.FromSeconds(2));
    17                 WriteLine(i);
    18             }
    19         }
    20 
    21         static void Main(string[] args)
    22         {
    23             WriteLine("Starting...");
    24             Thread t = new Thread(PrintNumbersWithDelay);
    25             t.Start();
    26             t.Join();
    27             WriteLine("Thread completed");
    28         }
    29     }
    30 }

    3、运行该控制台应用程序,运行效果如下图所示:

      在第26行代码处,我们在“Main”方法中调用调用“t.Join”方法,该方法允许我们等待线程t执行完毕后,再执行“Main”方法中剩余的代码。有了该技术,我们可以同步两个线程的执行步骤。第一个线程等待第二个线程执行完毕后,再进行其他的工作,在第一个线程等待期间,第一个线程的状态为“bolcked”状态,和我们调用Thread.Sleep的状态一样。

    四、终止线程

      在这一节中,我们将讲述如何终止另一个线程的执行。步骤如下:

    1、使用Visual Studio 2015创建一个新的控制台应用程序。

    2、双击打开“Program.cs”文件,编写如下代码:

     1 using System;
     2 using System.Threading;
     3 using static System.Console;
     4 using static System.Threading.Thread;
     5 
     6 namespace Recipe04
     7 {
     8     class Program
     9     {
    10         static void PrintNumbers()
    11         {
    12             WriteLine("Starting...");
    13 
    14             for (int i = 1; i < 10; i++)
    15             {
    16                 WriteLine(i);
    17             }
    18         }
    19 
    20         static void PrintNumbersWithDelay()
    21         {
    22             WriteLine("Starting...");
    23             for (int i = 1; i < 10; i++)
    24             {
    25                 Sleep(TimeSpan.FromSeconds(2));
    26                 WriteLine(i);
    27             }
    28         }
    29 
    30         static void Main(string[] args)
    31         {
    32             WriteLine("Starting program...");
    33             Thread t = new Thread(PrintNumbersWithDelay);
    34             t.Start();
    35             Thread.Sleep(TimeSpan.FromSeconds(6));
    36             t.Abort();
    37             WriteLine("A thread has been aborted");
    38             t = new Thread(PrintNumbers);
    39             t.Start();
    40             PrintNumbers();
    41         }
    42     }
    43 }

    3、运行该控制台应用程序,运行效果(每次运行效果可能不同)如下图所示:

      在第36行代码处,我们调用了“t.Abort”方法,该方法用于终止一个线程的执行。当Abort方法被调用时,会对目标线程注入“ThreadAbortException”异常,该异常将导致线程的终止,这是一种非常危险的操作,因为这个异常可能发生在任何时候,并有可能导致整个应用程序的销毁。因此,不推荐使用Abort方法来终止一个线程的执行,我们可以向线程提供一个“CancellationToken”对象来取消一个线程的执行,这个技术我们将在后续讲述。

      未完待续!

  • 相关阅读:
    [MFC美化] Skin++使用详解-使用方法及注意事项
    [MFC美化] SkinMagic使用详解3- 常见使用问题解答
    [MFC美化] SkinMagic使用详解2- SkinMagic常用函数介绍
    [MFC美化] SkinMagic使用详解1- SkinMagic使用流程
    MFC 自定义控件
    error C3872: “0x3000”: 此字符不允许在标识符中使用
    websocket学习
    Servlet学习1
    Git使用学习
    异常捕获测试
  • 原文地址:https://www.cnblogs.com/yonghuacui/p/6185610.html
Copyright © 2011-2022 走看看