C#线程开发之System.Thread类详解

一、属性

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

二、创建和控制线程

Thread 类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数。
ThreadStart委托定义了一个返回类型为void的无参数方法。在创建了 Thread对象后,就可以用Start()方法启动线程:

class Program
{
    static void Main()
    {
        var t1 = new Thread(ThreadMain);
        t1.Start();
        Console.WriteLine("This is the main thread.");
    }
    static void ThreadMain()
    {
        Console.WriteLine("Running in a thread.");
    }
}

Lambda表达式还可以与Thread类一起 使用,将线程方法的实现代码传送给Thread构造函数的实参:

static void Main()
{
    var t1 = new Thread(() => Console.WriteLine("running in a thread, id: {0}",Thread.CurrentThread.ManagedThreadId));
    t1.Start();
    Console.WriteLine("This is the main thread, id: {0}",
    Thread.CurrentThread.ManagedThreadId);
}

三、给线程传递参数

给线程传递一些数据可以采用两种方式。

1、ParameterizedThreadStart委托参数

要给线程传递数据,需要某个存储数据的类或结构。这里定义了包含字符串的Data结构,但可以传递任意对象.

static void Main()
{
    var d = new Data { Message = "Info" };
    var t2 = new Thread(ThreadMainWithParameters);//ParameterizedThreadStart委托实例
    t2.Start(d);
}
static void ThreadMainWithParameters(object o)//如果使用了 ParameterizedThreadStart委托,线程的入口点必须有一个object类型的参数,且返回类型为void。
{
    Data d = (Data)o;
    Console.WriteLine("Running in a thread, received {0}", d.Message);
}
public struct Data
{
    public string Message;
}

2、创建一个自定义类,把线程的方法定义为实例方法

给新线程传递数据的另一种方式是定义一个类(参见MyThread类),在其中定义需要的字段,将线程的调用的方法定义为类的一个实例方法:

static void Main()
{
    var obj = new MyThread("info");
    var t3 = new Thread(obj.ThreadMain);//实例方法
    t3.Start();
}
//实例方法
public class MyThread
{
    private string data;
    public MyThread(string data)
    {
        this.data = data;
    }
    public void ThreadMain()
    {
        Console.WriteLine("Running in a thread, data: {0}", data);
    }
}

四、后台线程

只要有一个前台线程在运行,应用程序的进程就在运行。
如果多个前台线程在运行,而Main()方法结束了,应用程序的进程就仍然是激活的,直到所有前台线程完成其任务为止。
在默认情况下,用Thread类创建的线程是前台线程。线程池屮的线程总是后台线程。
在用Thread类创建线程时,可以设置IsBackground属性,以确定该线程是前台线程还是后台线程。

五、线程的优先级

在Thread类中,可以设置Priority属性,以影响线程的基本优先级。Priority属性需要ThreadPriority 枚举定义的一个值。定义的级别有Highest、AboveNomal、BelowNormal和Lowest。

六、控制线程

  • 调用Thread对象的Start()方法,可以创建线程。但是,在调用Start()方法后,新线程仍不是处于Running状态,而是处于Unstarted状态。只要操作系统的线程调度器选择了要运行的线程,线程就会改为Running状态。读取Thread.ThreadState属性,就可以获得线程的当前状态。
  • 使用ThreadSleep()方法,会使线程处于WaitSleepJoin状态,在经历Sleep()方法定义的时间段后,线程就会等待再次被唤醒。
  • 要停止另一个线程,可以调用Thread.Abort() 方法。调用这个方法时,会在接到终止命令的线程中抛出一个ThreadAbortExcepticm类型的异常。用一个处理程序捕获这个异常,线程可以在结束前完成一些淸理工作。线程还可以在接收到调用Thread.ResetAbort()方法的结果ThreadAbortExcepdon 异常后继续运行。如果线程没有重置终止,接收到终止请求的线程的状态就从AbortRequested改为 Aborted。
  • 如果需要等待线程的结束,就可以调用Thread.Join()方法。Thread.Join()方法会停止当前线程, 并把它设置为WaitSleepJoin状态,直到加入的线程完成为止。
public class Worker
{
    // 此方法将在线程启动时调用。
    public void DoWork()
    {
        while (!_shouldStop)
        {
            Console.WriteLine("工作线程: working...");
        }
        Console.WriteLine("工作线程:正常停止");
    }
    public void RequestStop()
    {
        _shouldStop = true;
    }
    // Volatile用于提示编译器这个数据成员将被多个线程访问。
    private volatile bool _shouldStop;
}

static void Main()
{
    // 创建thread对象,但这不会启动线程。
    Worker workerObject = new Worker();
    Thread workerThread = new Thread(workerObject.DoWork);

    // 启动工作线程。
    workerThread.Start();
    Console.WriteLine("main thread: 启动工作线程...");

    // 循环,直到工作线程激活。
    while (!workerThread.IsAlive) ;

    // 将主线程休眠1毫秒,让工作线程做一些工作:
    Thread.Sleep(1);

    // 请求工作线程停止自身:
    workerObject.RequestStop();//workerObject.Abort()

    //使用Join方法阻塞当前线程,直到工作线程执行完毕才往下执行
    workerThread.Join();
    Console.WriteLine("main thread: 工作线程已经终止.");
}

七、使用线程实现回调

//定义一个委托实现回调函数
public delegate void CallBackDelegate(string message);

void Main()
{
    //委托实现方法和定义线程
    CallBackDelegate cbd = CallBack;
    Thread thread = new Thread(initFtpParam);
    thread.Start(cbd);
}

/// <summary>
/// 线程方法
/// </summary>
/// <param name="obj"></param>
public void initFtpParam(object obj)
{
    CallBackDelegate callBackDelegate = obj as CallBackDelegate;
    callBackDelegate("aa");//执行委托
}

/// <summary>
/// 回调方法
/// </summary>
/// <param name="message"></param>
private void CallBack(string message)
{
    Console.Write(message);
}

八、区域性和线程

  • CurrentUICulture属性可返回当前用户界面区域性。该属性由 ResourceManager 类用于在运行时查找区域性特定资源。
    可以使用非特定区域性、特定区域性或 InvariantCulture 来设置 CurrentUICulture 属性。
    默认值是操作系统用户界面语言。
  • CurrentCulture属性用来决定诸如货币、数字和日期如何格式化。
    CurrentCulture 属性不是一个语言设置。它仅包含与地理区域的标准设置相关的数据。因此,只能将 CurrentCulture 属性设置为特定区域性,比如"fr-FR"或 InvariantCulture。
    默认值是操作系统的User Locale,我们可以在控制面板里设置。CultureInfo.UseUserOverride属性指示是否使用用户在控制面板自定义的 数字、符号、日期、货币等的格式。

1、.NET4.5之前,只能用以下代码只能针对单个线程,如果每次执行线程 都要重新设置一下。。。
新开一个新线程,默认的CurrentCulture为系统的Culture,如果要改变当前线程的Culture,需要在线程中修改 Thread.CurrentCulture值来实现。

m.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");

2、如果使用的.net环境是4.5及以上版本,CultureInfo提供了两个静态属性DefaultThreadCulture和DefaultThreadUICulture,一处修改即可实现所有的未显式设置Thread.CurrentCulture的线程都使用这个Default值。

System.Globalization.CultureInfo.DefaultThreadCurrentCulture = new System.Globalization.CultureInfo("en-US");
System.Globalization.CultureInfo.DefaultThreadCurrentUICulture = new System.Globalization.CultureInfo("en-US");

到此这篇关于C#线程开发之System.Thread类的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • c# Thread类的用法详解

    Thread类相对于线程池中的线程,使用者有更多的控制权.该类允许创建前台线程,设置线程优先级等.Thread类的构造函数重载为接受ThreadStart和ParameterizedThreadStart类型的委托参数. 1.给线程传递数据 给线程传递数据的两种方式: 1.使用带ParameterizedThreadStart委托参数的Thread构造函数: //定义一个数据类型,传递给线程 public struct Data { public string Message; } //创建一个

  • c#线程Thread示例

    C#是一门支持多线程的语言,因此线程的使用也是比较常见的.由于线程的知识在Win32编程的时候已经说得过多,所以在.Net中很少介绍这部分(可能.Net不觉得这部分是它所特有的). 那么线程相关的问题大致有如下四类(这篇文章只讨论单线程.单线程与UI线程这两方面的问题).问题一,线程的基本操作,例如:暂停.继续.停止等:问题二,如何向线程传递参数或者从中得到其返回值:问题三,如何使线程所占用的CPU不要老是百分之百:最后一个,也是问题最多的,就是如何在子线程来控制UI中的控件,换句话说,就是在线

  • C#多线程Thread使用示例详解

    本文实例为大家分享了C#多线程Thread使用的示例代码,供大家参考,具体内容如下 多线程: 线程生命周期状态图: C#线程优先级(概率高低): 基本使用示例: using System; using System.Threading; namespace month_9_10._1009 { class Run5 { /* 测试线程的调用过程 * 主线程输出world,子线程输出hello */ public static void showHello() { for(int i = 0; i

  • C#多线程之Thread类详解

    使用System.Threading.Thread类可以创建和控制线程. 常用的构造函数有: // 摘要: // 初始化 System.Threading.Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托. // // 参数: // start: // System.Threading.ParameterizedThreadStart 委托,它表示此线程开始执行时要调用的方法. // // 异常: // System.ArgumentNullException: // star

  • C# 异步多线程入门到精通之Thread篇

    上一篇:C# 异步多线程入门基础 下一篇:C# 异步多线程入门到精通之ThreadPool篇 Thread API 这里对 Thread 的一些常用 API 进行介绍,使用一些案例进行说明.由于 Thread 的不可控与效率问题,Thread 现在已经不常用了,这里介绍一些 API ,想更深入的同学可以继续研究研究. Instance 首先看 Thread 的构造函数,有 ThreadStart .ParameterizedThreadStart .maxStackSize 类型的参数,这三个常

  • c# Thread类线程常用操作详解

    创建线程 线程是通过扩展 Thread 类创建的.扩展的 Thread 类调用 Start() 方法来开始子线程的执行. 下面的程序演示了这个概念: class ThreadCreationProgram { public static void CallToChildThread() { Console.WriteLine("Child thread starts"); } static void Main(string[] args) { ThreadStart childref

  • C# 中如何使用Thread

    线程是进程中的最小执行单元,多线程是指在给定时间内拥有多个线程的能力,并且可以调度它们从而在某一时刻处理多个操作,微软的 .Net Framework 提供了 Thread 来帮助我们完成多线程开发. Thread 编程 要想使用 Thread,需要在程序中引用 System.Threading 命名空间,然后再提供一个供线程调度的方法,这个方法是通过 Thread 中的 ThreadStart 委托代理的,下面的代码展示了如何创建线程. Thread t = new Thread(new Th

  • C#线程开发之System.Thread类详解

    一.属性 CurrentContext    获取线程正在其中执行的当前上下文. ExecutionContext    获取 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息. CurrentCulture    获取或设置当前线程的区域性. CurrentUICulture    获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源. CurrentThread    获取当前正在运行的线程. IsAlive    获取指示当前线程的执行状态的

  • JSP 开发之 releaseSession的实例详解

    JSP 开发之 releaseSession的实例详解 Hibernate可以实现分页查询,昨天试了一下,分页效果不错.但是发现了一个问题,就是当请求超过20次的时候页面就会卡死.经检查,是卡在分页查询这一块. 应用程序采用struts2 + spring2 + hibernate3架构 连接池配置使用的是c3p0, 最大池大小为20, 很显然是连接池耗尽导致的. 增加连接池大小只是饮鸩止渴,总还有耗尽的时候,必须找到根本原因. Dao类的分页查询方法如下: java 代码  public Li

  • Android音频开发之SurfaceView的使用详解

    目录 SurfaceView 不同点 双缓冲机制 SurfaceHolder 使用 SurfaceView SurfaceView从源码上看继承自View,但在内部实现上SurfaceView和其他View有很多区别. SurfaceView主要作用是提供一个直接绘图表面嵌入到视图结构中,实际上真正做绘制能力的是Surface.因此SurfaceView和宿主窗口是分离的.正常情况下窗口的View共享同一个Window,而Window也对应一个Surface,所有View也就共享同一个Surfa

  • Java中Thread类详解及常用的方法

    目录 一.Thread 的常见构造方法 二.Thread 的常见属性 三.创建线程 四.中断线程 五.线程等待 六.获取线程引用 七.线程休眠 八.线程状态 总结 一.Thread 的常见构造方法 方法 说明 Thread() 创建线程对象 Thread(Runnable target) 使用 Runnable 对象创建线程对象 Thread(String name) 创建线程对象并命名 Thread(Runnable target,String name) 使用 Runnable 对象创建线程

  • 安卓开发之FragmentPagerAdapter和FragmentStatePagerAdapter详解

    目录 FragmentPagerAdapter与FragmentPagerStateAdapter区别点: 一:二者在状态保存有差异:FragmentPagerAdapter并未实现saveState().restoreState() 二:二者在视图管理方法差异: 最近遇到比较奇怪的bug,TableLayout+ViewPager实现点击顶部tab切换viewpager视图.但是在Viewpager设置dapter时,最开始设置的是FragmentPagerAdapter,会导致tab切换后F

  • 移动web开发之touch事件实例详解

    前面的话 iOS版Safari为了向开发人员传达一些特殊信息,新增了一些专有事件.因为iOS设备既没有鼠标也没有键盘,所以在为移动Safari开发交互性网页时,常规的鼠标和键盘事件根本不够用.随着Android 中的WebKit的加入,很多这样的专有事件变成了事实标准,导致W3C开始制定Touch Events规范.本文将详细介绍移动端touch事件 概述 包含iOS 2.0软件的iPhone 3G发布时,也包含了一个新版本的Safari浏览器.这款新的移动Safari提供了一些与触摸(touc

  • iOS开发之UIMenuController使用示例详解

    目录 简介 接口介绍 使用探索 如何创建并显示 UIMenuController 实现 Item 点击事件 菜单 Item 太多??? UIResponderStandardEditActions 协议 添加自定义菜单 箭头的方向 实际使用 总结 简介 UIMenuController 是一个菜单编辑界面,在很多地方都能用到,通常用于剪切.复制.粘贴.选择.全选和删除命令等,也可以自定义想要的操作,它长这样: 接口介绍 open class UIMenuController : NSObject

  • Android开发之ContentProvider的使用详解

    前言         Content Provider为存储数据和获取数据提供了统一的接口,它可以完成在不同应用程序下的数据共享,而在上一篇文章Android开发之SQLite的使用方法讲到的SQLite只能在同一个程序中共享数据.另外android为一些常见的数据,比如说音频,视频,图片,通讯录等提供了Content Provider,这样我们就可以很方便的对这些类型的数据操作了.使用ContentProvider的好处是开发人员不需要考虑数据内部是怎么存储的,比如说如果我们想利用Conten

  • Android开发之Notification通知用法详解

    本文实例讲述了Android开发之Notification通知用法.分享给大家供大家参考,具体如下: 根据activity的生命周期,在activity不显示时,会执行onStop函数(比如按下home键),所以你在onStop函数(按退出键除外)里面把notification放在通知栏里,再此显示时,把notification从通知栏里去掉.或者,只要程序在运行就一直显示通知栏图标. 下面对Notification类中的一些常量,字段,方法简单介绍一下: 常量: DEFAULT_ALL 使用所

随机推荐