C#学习系列相关之多线程(二)----Thread类介绍

简介: C#学习系列相关之多线程(二)----Thread类介绍

一、线程初始化

1.无参数

static void Main(string[] args) {
        //第一种写法
        Thread thread = new Thread(test);
        thread.Start();
        //第二种写法 delegate
        Thread thread1 = new Thread(new ThreadStart(test));
        thread1.Start();
        //第三种写法 lambda
        Thread thread2 = new Thread(() => { test(); });
        thread2.Start();
 
        Console.WriteLine("mainThread");
        Console.Read();
    }
    static void test() {
        Console.WriteLine("hello");
    }

2.有参数

static void Main(string[] args) {
        object obj = "xxx";
        //第一种写法
        Thread thread = new Thread(test);
        thread.Start(obj);
        //第二种写法 delegate
        Thread thread1 = new Thread(new ParameterizedThreadStart(test));
        thread1.Start(obj);
        //第三种写法 lambda
        Thread thread2 = new Thread((arg) => { test(arg); });
        thread2.Start(obj);
 
        Console.WriteLine("mainThread");
        Console.Read();
    }
    static void test(object obj) {
        Console.WriteLine("hello" + obj);
    }

注意:1.thread.start()内填入的是实际传递的参数,arg为形参

          2.方法test中传递的参数数量为1,并且必须是object类型

二、线程开启

1.无参数传递

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Threading;  
 
namespace AAAAAA  
{  
  class AAA  
  {  
  public static void Main()  
  {  
  Thread t = new Thread(new ThreadStart(A));  
  t.Start();  
 
  Console.Read();  
  }  
 
  private static void A()  
  {  
  Console.WriteLine("Method A!");  
  }  
  }  
}

运行结果:Method A!


2.单个参数传递

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Threading;  
 
namespace AAAAAA  
{  
  class AAA  
  {  
  public static void Main()  
  {   
  Thread t = new Thread(new ParameterizedThreadStart(B));  
  t.Start("B");  
 
  Console.Read();  
  }  
 
  private static void B(object obj)  
  {  
  Console.WriteLine("Method {0}!",obj.ToString ());  
 
  }  
  }  
}

运行结果:Method B!

3.多个参数传递

第一种方法:将多个参数定义为类的属性,类内的方法

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Threading;  
 
namespace AAAAAA  
{  
  class AAA  
  {  
  public static void Main()  
  {  
  My m = new My();  
  m.x = 2;  
  m.y = 3;  
 
  Thread t = new Thread(new ThreadStart(m.C));  
  t.Start();  
 
  Console.Read();  
  }  
  }  
 
  class My  
  {  
  public int x, y;  
 
  public void C()  
  {  
  Console.WriteLine("x={0},y={1}", this.x, this.y);  
  }  
  }  
}

结果显示:x=2,y=3

第二种方法:该方法最为推荐的方法,定义结构体,通过object进行拆箱,将参数进行传递

//结构体  
  struct RowCol  
  {  
  public int row;  
  public int col;  
  };  
 
//定义方法  
public void Output(Object rc)  
  {  
  RowCol rowCol = (RowCol)rc;  
  for (int i = 0; i < rowCol.row; i++)  
  {  
  for (int j = 0; j < rowCol.col; j++)  
  Console.Write("{0} ", _char);  
  Console.Write("\n");  
  }  
  }

三、常用Thread类下的方法

常用属性:

常用方法介绍:

1、public bool IsBackground { get; set; } //表示此线程是否为后台线程

//false为前台线程,进程结束后,任务执行完毕以后,线程才结束

//true为后台线程,进程结束,线程结束

2、public int ManagedThreadId { get; } //获取当前线程唯一标识符

3、public void Abort(); //终止线程,其实就是抛出个异常

4、public void Suspend(); //挂起也就是暂停线程 (已被弃用)

5、public void Resume(); //将挂起的线程继续,也就是回复线程 (已被弃用)

6、public void ResetAbort(); //是把终止的线程再次启用,都会有延时的

7、public void Sleep(200) ; //线程睡眠

8、public bool Join(int millisecondsTimeout); //会阻塞,必须等到线程结束后才会执行下一步

public bool Join(TimeSpan timeout); //会阻塞,必须等到线程结束后才会执行下一步

9、public static void Sleep(int millisecondsTimeout); //线程睡眠

public static void Sleep(TimeSpan timeout); //线程睡眠

10、public void Start(); //另开线程开始执行

public void Start(object parameter); //另开线程开始,带参数

主要介绍三个方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace 线程test1005
{
    class Program
    {
         static void Main(string[] args)
        {
            Thread tt = new Thread(test);
            tt.Start();
            for (int i = 0; i < 300; i++)
            {
                Console.Write(2);
            }
            Console.Read();
        }
        static void test()
        {
            for (int i = 0; i < 300; i++)
            {
                Console.Write(1);
            }
        }
        
    }
}

正常运行的情况下1,2交替出现;

1.Abort用法

static void Main(string[] args)
        {
            Thread tt = new Thread(test);
            tt.Start();
            tt.Abort();
            for (int i = 0; i < 300; i++)
            {
                Console.Write(2);
            }
            Console.Read();
        }

当我们加入abort后运行结果:支线程被释放

Abort相当于方法内抛出一个异常,会执行方法中catch和finally中的代码

2.thread.ResetAbort用法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace 线程test1005
{
    class Program
    {
         static void Main(string[] args)
        {
            Thread tt = new Thread(test);
            tt.Start();
            Thread.Sleep(10);
            for (int i = 0; i < 300; i++)
            {
                Console.Write(2);
            }
            tt.Abort();
            Console.Read();
        }
        static void test()
        {
            try
            {
                while (true)
                {
                    for (int i = 0; i < 300; i++)
                    {
                        Console.Write(1);
                    }
                }
              
            }
            catch (Exception ex)
            {
                Console.WriteLine("子线程");
                Thread.ResetAbort();
            }
            finally
            {
                Console.WriteLine("这里是finally");
            }
            Console.WriteLine("最后");
        }
        
    }
}

可以看到线程被Abort之后,执行catch和finally块中的内容,但是不会执行finally块之后的内容。

从结果中可以看到,线程被终止了,由于执行了Thread.ResetAbort(),因此就允许继续执行finally块之后的代码。

注意: 如果Thread.ResetAbort()语句放在catch块中,最好应当把Thread.ResetAbort()语句放在catch{}代码块最后,否则会把abortException.ExceptionState中的内容给清空了。Thread.ResetAbort()还可以放在finally块中,它同样也可以允许继续执行finally块之后的代码。另外,Thread.ResetAbort()只能执行一次,不能执行二次及以上,否则会出新的异常。

3.thread.join用法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace 线程test1005
{
    class Program
    {
         static void Main(string[] args)
        {
            Thread tt = new Thread(test);
            tt.Start();
            tt.Join();
            for (int i = 0; i < 300; i++)
            {
                Console.Write(2);
            }
            tt.Abort();
            Console.Read();
        }
        static void test()
        {
            for (int i = 0; i < 300; i++)
            {
                Console.Write(1);
            }
        }
    }
}

运行结果:

tt.join()可以先执行tt线程内的内容,等执行完成后,再执行主线程中的内容

tt.join(1000)线程会等待一段时间(10000ms),若这段时间内工作线程没挂掉,一旦超过这个时间,主线程便会开始工作

小技巧:1.abort()的功能是用来终止调用此方法的线程的,只是在多数情况下,它需要一点时间,有些延迟(可能在短时间内此线程还在执行)...
2.join()方法它的功能不是终止线程,而是在t 线程终止之前,阻止正在结束(调用了abort()方法但还未结束)的t 线程执行,同时使主线程等待,直到t线程终止(也就是abort()方法终止过程完毕)了再执行下面的代码,打印出来的结果,执行状态就为FALSE,线程状态也为停止了。

Join常用让子线程完全终止!

 


相关文章
|
1月前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
2月前
|
监控 Java 调度
【Java学习】多线程&JUC万字超详解
本文详细介绍了多线程的概念和三种实现方式,还有一些常见的成员方法,CPU的调动方式,多线程的生命周期,还有线程安全问题,锁和死锁的概念,以及等待唤醒机制,阻塞队列,多线程的六种状态,线程池等
132 6
【Java学习】多线程&JUC万字超详解
|
1月前
|
Java 程序员 C#
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
13 0
|
2月前
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
27 2
|
2月前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
79 0
|
6月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
194 3
|
6月前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
199 3
|
17天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
29 3
|
1月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
106 0