CLR线程、线程池、任务的这些事-阿里云开发者社区

开发者社区> 狗尾巴呢> 正文

CLR线程、线程池、任务的这些事

简介: CLR线程 CLR使用的是Windows的线程处理能力,目前的CLR实现一个CLR线程对应于一个Windows线程 System.Threading.Thread       System.Threading.Thread t = new System.Threading.Thread(op =>       {           Console.WriteLine(op);       });       t.Start("demo");       t.Join();  CLR线程池 创建和销毁线程是一个昂贵的操作,要耗费大量时间、资源,对性能也有影响。
+关注继续查看

CLR线程

CLR使用的是Windows的线程处理能力,目前的CLR实现一个CLR线程对应于一个Windows线程

System.Threading.Thread

      System.Threading.Thread t = new System.Threading.Thread(op =>

      {

          Console.WriteLine(op);

      });

      t.Start("demo");

      t.Join();

 

CLR线程池

创建和销毁线程是一个昂贵的操作,要耗费大量时间、资源,对性能也有影响。为改善这个情况,CLR包含了代码来管理它的线程池。可将线程池想象成可由你的程序使用的一个线程集合,每个CLR一个线程池,这个线程池可由CLR控制的所有AppDomian共享。如果一个进程加载了多个CLR,每个CLR都有自己的线程池。

        System.Threading.ThreadPool.QueueUserWorkItem(op =>

        {

            Console.WriteLine(op);

        },

        "demo");

 

执行上下文

每个线程都关联一个执行上下文结构,包括:安全设置(Thread.Principal Windows身份)、宿主设置(System.Threading.HostExecutionContextManager)、逻辑调用上下文数据(System.Runtime.Remoting.Messaging.CallContextLogicSetDataLogicGetData)

默认情况下,CLR自动造成初始线程的执行上下文复制到任何辅助线程,如果需要控制上下文的复制问题,可使用System.Threading.ExecutionContext类,如:

     // Put some data into the Main thread’s logical call context

        CallContext.LogicalSetData("Name""Jeffrey");

 

        // Initiate some work to be done by a thread pool thread

        // The thread pool thread can access the logical call context data 

        ThreadPool.QueueUserWorkItem(

           state => Console.WriteLine("Name={0}"CallContext.LogicalGetData("Name")));

 

 

        // Suppress the flowing of the Main thread’s execution context

        ExecutionContext.SuppressFlow();

 

        // Initiate some work to be done by a thread pool thread

        // The thread pool thread can NOT access the logical call context data

        ThreadPool.QueueUserWorkItem(

           state => Console.WriteLine("Name={0}"CallContext.LogicalGetData("Name")));

 

        // Restore the flowing of the Main thread’s execution context in case 

        // it employs more thread pool threads in the future

        ExecutionContext.RestoreFlow();

 

协作式取消

.net提供了标准的取消操作模式

   private static void CancellingAWorkItem() {

        CancellationTokenSource cts = new CancellationTokenSource();

        // Pass the CancellationToken and the number-to-count-to into the operation

        ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));

 

        Console.WriteLine("Press <Enter> to cancel the operation.");

        Console.ReadLine();

        cts.Cancel();  // If Count returned already, Cancel has no effect on it

        // Cancel returns immediately, and the method continues running here...

 

        Console.ReadLine();  // For testing purposes

    }

    private static void Count(CancellationToken token, Int32 countTo) {

        for (Int32 count = 0; count < countTo; count++) {

            if (token.IsCancellationRequested) {

                Console.WriteLine("Count is cancelled");

                break// Exit the loop to stop the operation

            }

 

            Console.WriteLine(count);

            Thread.Sleep(200);   // For demo, waste some time

        }

        Console.WriteLine("Count is done");

    }

任务

ThreadPool.QueueUserWorkItem虽然简单,担忧如下限制:

Ø  没有内建的机制知道操作什么时候完成

Ø  没有内建的机制在操作完成时获得一个返回值

System.Threading.Tasks下的类型可解决这个问题

      Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 10000);

 

        // You can start the task sometime later

        t.Start();

 

        // Optionally, you can explicitly wait for the task to complete

        t.Wait(); // FYI: Overloads exist accepting a timeout/CancellationToken

 

        // Get the result (the Result property internally calls Wait) 

        Console.WriteLine("The sum is: " + t.Result);   // An Int32 value

 

任务的取消使用“协作式取消”方式,CancellationTokenSource

 

一个任务完成时自动启动另一个新任务

Task.ContinueWith

 

任务可以启动子任务

 

任务工厂

         有时,可能需要创建一组Task对象来共享相同的状态,为了避免机械的将相同的参数传给每个Task的构造器,可以创建一个任务工厂来封装通用的状态。

 

 

参考

Clr Via C# 25 26

http://transbot.blog.163.com

http://ys-f.ys168.com/?CLR_via_CSharp_3rd_Edition_Code_by_Jeffrey_Richter.zip_55bism1e0e7bkisjthit2bso0cm5bs4bs1b5bktnql0c0bu22f05f12z

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10081 0
Android多线程任务优化1:探讨AsyncTask的缺陷
 AsyncTask还有别的缺陷,在生成listview的时候,如果adapter里面的count动态改变的话,不能使用AsyncTask,只能使用Thread+Handler,否则会出现如下错误java.
1044 0
CLR线程、线程池、任务的这些事
CLR线程 CLR使用的是Windows的线程处理能力,目前的CLR实现一个CLR线程对应于一个Windows线程 System.Threading.Thread       System.Threading.Thread t = new System.Threading.Thread(op =>       {           Console.WriteLine(op);       });       t.Start("demo");       t.Join();  CLR线程池 创建和销毁线程是一个昂贵的操作,要耗费大量时间、资源,对性能也有影响。
1039 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10883 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13887 0
+关注
狗尾巴呢
从事研发20年 涉及桌面软件、嵌入式设备、C/S分层系统、B/S业务系统、互联网系统等等各类系统 语言涉及C/C++ .net系统 java系列 前端系列等等不同的类别 主控和主导了国家863项目,企业业务应用系统,自然语言翻译系统,数据库审计等系列的软件研发
435
文章
2
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载