三沣开发知识 购物 网址 小说 美女秀 游戏 电影下载 图说天下 生肖星座 新闻 笑话 | IT开发 软件下载 手机论坛 三沣软件 360图书馆
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> C# -> C# Task 源代码阅读(1) -> 正文阅读
 

[C#]C# Task 源代码阅读(1)

C# Task 源代码阅读(1) 平时我们开发中,经常使用Task,后续的.net版本种很多都和Task有关,比如asyn,await有了Task 我们很少就去关注Thread 了。Task 给我们带来了很多的便利之处。是我们更少的去关注执行的历程,更多的去关注逻辑。但是有些时候,有些应用。又不得不考虑task 的运行状况,比如这个任务成功与否,是否发生异常。经常听别人说到task 是在线程池执行的,那我们今天就来看看task 到底在做什么了,他执行的时候又做些哪些工作。
大家可以从这里可以看到Task 的源代码,也可以从reference code 直接download 下来。
我们先来看这段代码

public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable
    {
        [ThreadStatic]
        internal static Task t_currentTask;  // The currently executing task.
        [ThreadStatic]
        private static StackGuard t_stackGuard;  // The stack guard object for this thread

        internal static int s_taskIdCounter; //static counter used to generate unique task IDs
        private readonly static TaskFactory s_factory = new TaskFactory();

        private volatile int m_taskId; // this task's unique ID. initialized only if it is ever requested

        internal object m_action;    // The body of the task.  Might be Action<object>, Action<TState> or Action.  Or possibly a Func.
        // If m_action is set to null it will indicate that we operate in the
        // "externally triggered completion" mode, which is exclusively meant 
        // for the signalling Task<TResult> (aka. promise). In this mode,
        // we don't call InnerInvoke() in response to a Wait(), but simply wait on
        // the completion event which will be set when the Future class calls Finish().
        // But the event would now be signalled if Cancel() is called
}

先看Task 类继承的接口,IThreadPoolItem 这个和线程池相关,IAsyncResult这个和异步执行的回掉相关,这里我不在过多说这个,
接着我们看到有个字段t_currentTask ,而且是static 的,指向本身的task。大家不知道会不会有疑问,为什么这样设计呢,其实这样的设计在.net很多地方都有,比如HttpContext等等,特点基本都会有个Current。这种有点类似单例模式,但是开始已经初始化好,还有个更多的有点你可以随时替换,注入你自己的定义的东西。把他当作单例来用也是完全ok。注意了这里的访问修饰符是internal static。
接着t_stackGuard,s_taskIdCounter 顾名思义不在过多介绍。
下面就是s_factory 注意他是static 和访问修饰符,当然我如果用工厂模式,一般很少会把当前的工厂放在类内部来使用。哪天我要给我生产出的成品当然得这么做了。
接着一个比较重要的字段m_action ,执行体。大家是否记得在汇编里是如何执行所谓函数的,push a push b call xxxx。a,b 分别是参数,xxxx 为跳转地址 执行代码,参数的传递一般是通过stack 来传递。在net 这里直接放成object ,而且注释写的很清楚无非是那些委托。但是对一个函数来说,他的执行体就是call 的地址。
接着我们看下面的字段

        internal object m_stateObject; // A state object that can be optionally supplied, passed to action.
        internal TaskScheduler m_taskScheduler; // The task scheduler this task runs under. 

        internal readonly Task m_parent; // A task's parent, or null if parent-less.


        internal volatile int m_stateFlags;

m_stateObject 一猜也大概直到作用。
下面又是一个执行过程特别重要的字段m_taskScheduler,在执行过程比较重要。 大家平时windows 的平台的taskScheduler可能用的比较多,说到taskScheduler,功能也就是在合理时间安排合理的task 执行,实际上就是一个执行管理器。当然我们在sql server 的开发工具也有类似的工作,job 的执行,我们也是要选择执行计划的。当然这里的m_taskScheduler 也许是有本身的意思,都是任务调度器。当然task 默认的taskScheduler与我们刚刚提到的工具功能差距有点大。当然,大家有个印象,就是用来调度task 的。至于怎么调度,各自有各自的方案。
m_stateFlags 状态标志字段。一个Task 的执行,我当然很想直到他当前的状态,开始,结束,所以这个也好理解。本身在Thread 种就有很多状态。
继续看代码

   public void Start()
        {
            Start(TaskScheduler.Current);
        }
public void Start(TaskScheduler scheduler)
        {
            // Read the volatile m_stateFlags field once and cache it for subsequent operations
            int flags = m_stateFlags;

            // Need to check this before (m_action == null) because completed tasks will
            // set m_action to null.  We would want to know if this is the reason that m_action == null.
            if (IsCompletedMethod(flags))
            {
                throw new InvalidOperationException(Environment.GetResourceString("Task_Start_TaskCompleted"));
            }

            if (scheduler == null)
            {
                throw new ArgumentNullException("scheduler");
            }

            var options = OptionsMethod(flags);
            if ((options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
            {
                throw new InvalidOperationException(Environment.GetResourceString("Task_Start_Promise"));
            }
            if ((options & (TaskCreationOptions)InternalTaskOptions.ContinuationTask) != 0)
            {
                throw new InvalidOperationException(Environment.GetResourceString("Task_Start_ContinuationTask"));
            }

            // Make sure that Task only gets started once.  Or else throw an exception.
            if (Interlocked.CompareExchange(ref m_taskScheduler, scheduler, null) != null)
            {
                throw new InvalidOperationException(Environment.GetResourceString("Task_Start_AlreadyStarted"));
            }

            ScheduleAndStart(true);
        }

我们平常都会用start方法,他会默认传入一个TaskScheduler,我们接着看下面的方法,最后调用的是ScheduleAndStart方法,不管前面的验证,我们重点看执行流程,要弄清这点,我们必须清楚TaskScheduler.Current
到底是什么类,他的功能是什么,如果我们自己去写TaskScheduler,那又该去写什么,完成哪些功能。
我们继续从reference code 找到TaskScheduler 类。我们先重点追踪Current ,先不管方法。

 public static TaskScheduler Current 
        {
            get
            {
                TaskScheduler current = InternalCurrent;
                return current ?? TaskScheduler.Default;
            }
        }
 internal static TaskScheduler InternalCurrent
        {
            get
            {
                Task currentTask = Task.InternalCurrent;
                return ( (currentTask != null) 
                    && ((currentTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
                    ) ? currentTask.ExecutingTaskScheduler : null;
            }
        }


默认我继续找到default 属性


public static TaskScheduler Default 
        {
            get
            {
                return s_defaultTaskScheduler;
            }
        }
   private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler();


我们一步一步追踪,终于找到了ThreadPoolTaskScheduler,这时终于可以task 把threadpool 联系起来了。

再看执行
ScheduleAndStart之前,我们看下


  if (Interlocked.CompareExchange(ref m_taskScheduler, scheduler, null) != null)
 这句的写法,null 判断再加上对象的赋值。这个我们可以在平时的代码中加以借用。






  C# 最新文章
使用mongodb作为Quartz.Net下的JobStore实现
Log4Net记录到MySql
C# BackgroundWorker 的使用
C#定时发送邮箱设置
C# FTP操作类
C# 视频转换类
04.C#类型系统、值类型和引用类型(二章2.2
C#常用的IO操作方法
8、C#基础整理(数组和冒泡排序)
csharp: SQL Server 2005 Database Backup
上一篇文章      下一篇文章      查看所有文章
加:2017-04-06 01:50:35  更:2017-05-14 20:03:07 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 母婴/育儿 软件开发资料 网页快照 文字转语音 购物精选 软件 美食菜谱 新闻中心 电影下载 小游戏 Chinese Culture
生肖星座解梦 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图 中国文化英文 多播视频
2017-6-29 11:51:07
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库