C#(四十一)之线程

简介: 线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。

QQ图片20220426161529.jpg

线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。


C#线程操作,需要使用到Thread类。


使用命名空间


using System.Threading;


下表列出了 Thread 类的一些常用的 属性


属性 描述
CurrentContext 获取线程正在其中执行的当前上下文。
CurrentCulture 获取或设置当前线程的区域性。
CurrentPrinciple 获取或设置线程的当前负责人(对基于角色的安全性而言)。
CurrentThread 获取当前正在运行的线程。
CurrentUICulture 获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源。
ExecutionContext 获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。
IsAlive 获取一个值,该值指示当前线程的执行状态。
IsBackground 获取或设置一个值,该值指示某个线程是否为后台线程。(线程未停止时才好用)
IsThreadPoolThread 获取一个值,该值指示线程是否属于托管线程池。
ManagedThreadId 获取当前托管线程的唯一标识符。
Name 获取或设置线程的名称。
Priority 获取或设置一个值,该值指示线程的调度优先级。
ThreadState 获取一个值,该值包含当前线程的状态。

 

下表列出了 Thread 类的一些常用的 方法:


序号 方法名&描述
1 public void Abort()   在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。调用此方法通常会终止线程。
2 public static LocalDataStoreSlot AllocateDataSlot()   在所有的线程上分配未命名的数据槽。为了获得更好的性能,请改用以 ThreadStaticAttribute   属性标记的字段。
3 public static LocalDataStoreSlot AllocateNamedDataSlot(   string name)   在所有线程上分配已命名的数据槽。为了获得更好的性能,请改用以   ThreadStaticAttribute 属性标记的字段。
4 public static void BeginCriticalRegion()   通知主机执行将要进入一个代码区域,在该代码区域内线程中止或未经处理的异常的影响可能会危害应用程序域中的其他任务。
5 public static void BeginThreadAffinity()   通知主机托管代码将要执行依赖于当前物理操作系统线程的标识的指令。
6 public static void EndCriticalRegion()   通知主机执行将要进入一个代码区域,在该代码区域内线程中止或未经处理的异常仅影响当前任务。
7 public static void EndThreadAffinity()   通知主机托管代码已执行完依赖于当前物理操作系统线程的标识的指令。
8 public static void FreeNamedDataSlot(string name)   为进程中的所有线程消除名称与槽之间的关联。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。
9 public static Object GetData( LocalDataStoreSlot slot   )   在当前线程的当前域中从当前线程上指定的槽中检索值。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。
10 public static AppDomain GetDomain()   返回当前线程正在其中运行的当前域。
11 public static AppDomain GetDomainID()   返回唯一的应用程序域标识符。
12 public static LocalDataStoreSlot GetNamedDataSlot(   string name )   查找已命名的数据槽。为了获得更好的性能,请改用以   ThreadStaticAttribute 属性标记的字段。
13 public void Interrupt()   中断处于 WaitSleepJoin 线程状态的线程。
14 public void Join()   在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻塞调用线程,直到某个线程终止为止。此方法有不同的重载形式。
15 public static void MemoryBarrier()   按如下方式同步内存存取:执行当前线程的处理器在对指令重新排序时,不能采用先执行 MemoryBarrier 调用之后的内存存取,再执行 MemoryBarrier 调用之前的内存存取的方式。
16 public static void ResetAbort()   取消为当前线程请求的 Abort。
17 public static void SetData( LocalDataStoreSlot slot,   Object data )   在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。为了获得更好的性能,请改用以 ThreadStaticAttribute 属性标记的字段。
18 public void Start()   开始一个线程。
19 public static void Sleep( int millisecondsTimeout   )   让线程暂停一段时间。
20 public static void SpinWait( int iterations )   导致线程等待由 iterations 参数定义的时间量。
21 public static byte VolatileRead( ref byte address )   public static double VolatileRead( ref double address )   public static int VolatileRead( ref int address )   public static Object VolatileRead( ref Object address )   读取字段值。无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。此方法有不同的重载形式。这里只给出了一些形式。
22 public static void VolatileWrite( ref byte address,   byte value )   public static void VolatileWrite( ref double address, double value )   public static void VolatileWrite( ref int address, int value )   public static void VolatileWrite( ref Object address, Object value )   立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。此方法有不同的重载形式。这里只给出了一些形式。
23 public static bool Yield()   导致调用线程执行准备好在当前处理器上运行的另一个线程。由操作系统选择要执行的线程。

 


线程优先级(ThreadPriority):


Highest:最高

AboveNormal:第二高

Normal:默认级别

BelowNormal:较低

Lowest:最低

 

插入线程优先运行插入自身及插入之上的线程


static void Main(string[] args)
        {
            // 委托
            ThreadStart th = new ThreadStart(function);
            Thread threadA = new Thread(th);
            // 匿名委托
            Thread threadB = new Thread(delegate()
            {
                for (int i = 0; i < 500000000; i++)
                {
                    if (i % 1000000 == 0)
                    {
                        Console.WriteLine("B");
                    }
                }
                // 插入线程
                threadA.Join();
                // 主线程
                for (int i = 0; i < 500000000; i++)
                {
                    if (i % 1000000 == 0)
                    {
                        Console.WriteLine("主线程结束");
                    }
                }
            });
            // 设置线程优先级
            //threadA.Priority = ThreadPriority.AboveNormal;
            //threadB.Priority = ThreadPriority.BelowNormal;
            // 开启线程
            threadA.Start();
            threadB.Start();
            Console.ReadKey();
        }


打印结果:AAABBBAAABBB……主线程结束主线程结束主线程结束主线程结束主线程结束


C# ThreadState属性


这个属性代表了线程运行时状态,在不同的情况下有不同的值,我们有时候可以通过对该值的判断来设计程序流程。


C# ThreadState属性的取值如下:  

 

Aborted:线程已停止;    

AbortRequested:线程的Thread.Abort()方法已被调用,但是线程还未停止;    

Background:线程在后台执行,与属性Thread.IsBackground有关;    

Running:线程正在正常运行;    

Stopped:线程已经被停止;    

StopRequested:线程正在被要求停止;    

Suspended:线程已经被挂起(此状态下,可以通过调用Resume()方法重新运行);    

SuspendRequested:线程正在要求被挂起,但是未来得及响应;    

Unstarted:未调用Thread.Start()开始线程的运行;    

WaitSleepJoin:线程因为调用了Wait(),Sleep()或Join()等方法处于封锁状态;


实例:


private void button3_Click(object sender, EventArgs e)
        {
            Thread ss = new Thread( delegate(){
                Console.WriteLine("325432432");
            });
            string res = ss.ThreadState.ToString();
            ss.Start();
            res = ss.ThreadState.ToString();
            label1.Text = res;
        }

 

IsBackground:设置或取值,是否是后台线程,必须在线程运行的时候才好用

后台线程在应用程序关闭时,线程也随之关闭。他不会妨碍程序的运行


private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                ss.IsBackground = true;
                res = ss.ThreadState.ToString();
                label1.Text = res;
            }
            catch (Exception qq)
            {
                MessageBox.Show(qq.Message);
            }
        }

 

IsAlive:线程是否启动。返回true/false


private void button7_Click(object sender, EventArgs e)
        {
            try
            {
                res = ss.IsAlive.ToString();
                label1.Text = res;
            }
            catch (Exception qq)
            {
                MessageBox.Show(qq.Message);
            }
        }


测试使用全部代码


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
namespace Threads
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public string path ;
        public Thread th;
        /// <summary>
        /// 加载函数
        /// </summary>
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                path = textBox1.Text.Trim();
                if (path == "")
                {
                    MessageBox.Show("请输入文件路径");
                }
                if (File.Exists(path))
                {
                    OpenFile();
                }
                else
                {
                    MessageBox.Show("文件不存在");
                }
            }
            catch (Exception qq)
            {
                MessageBox.Show(qq.Message);
            }
        }
        /// <summary>
        /// 打开文件
        /// </summary>
        public void OpenFile()
        {
            string content = File.ReadAllText(path);
        }
        /// <summary>
        /// 打开线程
        /// </summary>
        public void OpenThread()
        {
            int a = 1;
            ThreadStart aaa = new ThreadStart(OpenFile);
            th = new Thread(aaa);
        }
        public void LookThread()
        {
            ///th.CurrentThread;
        }
        private void button5_Click(object sender, EventArgs e)
        {
            LookThread();
        }
        public Thread ss;
        public string res;
        // d
        private void button3_Click(object sender, EventArgs e)
        {
            ss = new Thread( delegate(){
                for (int i = 0; i < 1000000000000; i++)
                {
                    Console.WriteLine(i);
                }
            });
            res = ss.ThreadState.ToString();
            ss.Start();
            res = ss.ThreadState.ToString();
            label1.Text = res;
        }
        private void Stop_Click(object sender, EventArgs e)
        {
            ss.Abort();
            res = ss.ThreadState.ToString();
            label1.Text = res;
        }
        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                ss.IsBackground = true;
                res = ss.ThreadState.ToString();
                label1.Text = res;
            }
            catch (Exception qq)
            {
                MessageBox.Show(qq.Message);
            }
        }
        private void button7_Click(object sender, EventArgs e)
        {
            try
            {
                res = ss.IsAlive.ToString();
                label1.Text = res;
            }
            catch (Exception qq)
            {
                MessageBox.Show(qq.Message);
            }
        }
    }
}



目录
相关文章
|
9天前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
|
2月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
2月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
2月前
|
C#
C#学习相关系列之多线程---ConfigureAwait的用法
C#学习相关系列之多线程---ConfigureAwait的用法
|
2月前
|
C#
C#学习相关系列之多线程---TaskCompletionSource用法(八)
C#学习相关系列之多线程---TaskCompletionSource用法(八)
|
2月前
|
Java C#
C#学习系列相关之多线程(五)----线程池ThreadPool用法
C#学习系列相关之多线程(五)----线程池ThreadPool用法
|
2月前
|
并行计算 安全 Java
C# .NET面试系列四:多线程
<h2>多线程 #### 1. 根据线程安全的相关知识,分析以下代码,当调用 test 方法时 i > 10 时是否会引起死锁? 并简要说明理由。 ```c# public void test(int i) { lock(this) { if (i > 10) { i--; test(i); } } } ``` 在给定的代码中,不会发生死锁。死锁通常是由于两个或多个线程互相等待对方释放锁而无法继续执行的情况。在这个代码中,只有一个线程持有锁,且没有其他线程参与,因此不
106 3
|
7月前
|
C#
C#线程锁
C#线程锁
20 1
|
7月前
|
开发框架 Java .NET
C# 多线程编程二
C# 多线程编程二
57 0
|
5月前
|
IDE C# 开发工具
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
批量下载文件时使用多线程可以有效缩短完成时间,本文将讲解如何使用C#+CodePlus扩展库快速完成多线程的文件下载。 大部分代码由IDE自动生成,需要我们自己编写的代码正好**10行**。也就是说,只需要10分钟,就可以手撸一个多线程的批量下载器。
89 0
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)