.NET Task揭秘(一)
public static Task Run(Action action, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew((Task) null, (Delegate) action, (object) null, cancellationToken, TaskScheduler.Default, TaskCreationOptions.DenyChildAttach, InternalTaskOptions.None, ref stackMark);
}
public Task StartNew(Action<object> action, object state, CancellationToken cancellationToken)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Task internalCurrent = Task.InternalCurrent;
return Task.InternalStartNew(internalCurrent, (Delegate) action, state, cancellationToken, this.GetDefaultScheduler(internalCurrent), this.m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
}
private TaskScheduler GetDefaultScheduler(Task currTask)
{
if (this.m_defaultScheduler != null)
return this.m_defaultScheduler;
if (currTask != null && (currTask.CreationOptions & TaskCreationOptions.HideScheduler) == TaskCreationOptions.None)
return currTask.ExecutingTaskScheduler;
return TaskScheduler.Default;
}
public abstract class TaskScheduler
{
private static readonly ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers = new ConditionalWeakTable<TaskScheduler, object>();
private static readonly TaskScheduler s_defaultTaskScheduler = (TaskScheduler) new ThreadPoolTaskScheduler();
...
}
internal static Task InternalStartNew(Task creatingTask, Delegate action, object state, CancellationToken cancellationToken, TaskScheduler scheduler, TaskCreationOptions options, InternalTaskOptions internalOptions, ref StackCrawlMark stackMark)
{
if (scheduler == null)
throw new ArgumentNullException("scheduler");
Task task = new Task(action, state, creatingTask, cancellationToken, options, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler);
task.PossiblyCaptureContext(ref stackMark);
task.ScheduleAndStart(false);
return task;
}
internal Task(Delegate action, object state, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
{
if (action == null)
throw new ArgumentNullException("action");
if ((creationOptions & TaskCreationOptions.AttachedToParent) != TaskCreationOptions.None || (internalOptions & InternalTaskOptions.SelfReplicating) != InternalTaskOptions.None)
this.m_parent = parent;
this.TaskConstructorCore((object) action, state, cancellationToken, creationOptions, internalOptions, scheduler);
}
internal void TaskConstructorCore(object action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
{
this.m_action = action;
this.m_stateObject = state;
this.m_taskScheduler = scheduler;
if ((creationOptions & ~(TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously)) != TaskCreationOptions.None)
throw new ArgumentOutOfRangeException("creationOptions");
if ((creationOptions & TaskCreationOptions.LongRunning) != TaskCreationOptions.None && (internalOptions & InternalTaskOptions.SelfReplicating) != InternalTaskOptions.None)
throw new InvalidOperationException(Environment.GetResourceString("Task_ctor_LRandSR"));
int num = (int) (creationOptions | (TaskCreationOptions) internalOptions);
if (this.m_action == null || (internalOptions & InternalTaskOptions.ContinuationTask) != InternalTaskOptions.None)
num |= ;
this.m_stateFlags = num;
if (this.m_parent != null && (creationOptions & TaskCreationOptions.AttachedToParent) != TaskCreationOptions.None && (this.m_parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == TaskCreationOptions.None)
this.m_parent.AddNewChild();
if (!cancellationToken.CanBeCanceled)
return;
this.AssignCancellationToken(cancellationToken, (Task) null, (TaskContinuation) null);
}
internal static ExecutionContext Capture(ref StackCrawlMark stackMark, ExecutionContext.CaptureOptions options)
{
ExecutionContext.Reader executionContextReader = Thread.CurrentThread.GetExecutionContextReader();
if (executionContextReader.IsFlowSuppressed)
return (ExecutionContext) null;
SecurityContext securityContext = SecurityContext.Capture(executionContextReader, ref stackMark);
HostExecutionContext executionContext1 = HostExecutionContextManager.CaptureHostExecutionContext();
SynchronizationContext synchronizationContext = (SynchronizationContext) null;
LogicalCallContext logicalCallContext = (LogicalCallContext) null;
if (!executionContextReader.IsNull)
{
if ((options & ExecutionContext.CaptureOptions.IgnoreSyncCtx) == ExecutionContext.CaptureOptions.None)
synchronizationContext = executionContextReader.SynchronizationContext == null ? (SynchronizationContext) null : executionContextReader.SynchronizationContext.CreateCopy();
if (executionContextReader.LogicalCallContext.HasInfo)
logicalCallContext = executionContextReader.LogicalCallContext.Clone();
}
Dictionary<IAsyncLocal, object> dictionary = (Dictionary<IAsyncLocal, object>) null;
List<IAsyncLocal> asyncLocalList = (List<IAsyncLocal>) null;
if (!executionContextReader.IsNull)
{
dictionary = executionContextReader.DangerousGetRawExecutionContext()._localValues;
asyncLocalList = executionContextReader.DangerousGetRawExecutionContext()._localChangeNotifications;
}
if ((options & ExecutionContext.CaptureOptions.OptimizeDefaultCase) != ExecutionContext.CaptureOptions.None && securityContext == null && (executionContext1 == null && synchronizationContext == null) && ((logicalCallContext == null || !logicalCallContext.HasInfo) && (dictionary == null && asyncLocalList == null)))
return ExecutionContext.s_dummyDefaultEC;
ExecutionContext executionContext2 = new ExecutionContext();
executionContext2.SecurityContext = securityContext;
if (executionContext2.SecurityContext != null)
executionContext2.SecurityContext.ExecutionContext = executionContext2;
executionContext2._hostExecutionContext = executionContext1;
executionContext2._syncContext = synchronizationContext;
executionContext2.LogicalCallContext = logicalCallContext;
executionContext2._localValues = dictionary;
executionContext2._localChangeNotifications = asyncLocalList;
executionContext2.isNewCapture = true;
return executionContext2;
}
internal void ScheduleAndStart(bool needsProtection)
{
if (needsProtection)
{
if (!this.MarkStarted())
return;
}
else
this.m_stateFlags = this.m_stateFlags | ;
if (Task.s_asyncDebuggingEnabled)
Task.AddToActiveTasks(this);
if (AsyncCausalityTracer.LoggingOn && (this.Options & (TaskCreationOptions) ) == TaskCreationOptions.None)
AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "Task: " + ((Delegate) this.m_action).Method.Name, 0UL);
try
{
this.m_taskScheduler.InternalQueueTask(this);
}
catch (ThreadAbortException ex)
{
this.AddException((object) ex);
this.FinishThreadAbortedTask(true, false);
}
catch (System.Exception ex)
{
TaskSchedulerException schedulerException = new TaskSchedulerException(ex);
this.AddException((object) schedulerException);
this.Finish(false);
if ((this.Options & (TaskCreationOptions) ) == TaskCreationOptions.None)
this.m_contingentProperties.m_exceptionsHolder.MarkAsHandled(false);
throw schedulerException;
}
} internal void InternalQueueTask(Task task)
{
task.FireTaskScheduledIfNeeded(this);
this.QueueTask(task);
}
private static readonly ParameterizedThreadStart s_longRunningThreadWork = new ParameterizedThreadStart(ThreadPoolTaskScheduler.LongRunningThreadWork);
private static void LongRunningThreadWork(object obj)
{
(obj as Task).ExecuteEntry(false);
}
protected internal override void QueueTask(Task task)
{
if ((task.Options & TaskCreationOptions.LongRunning) != TaskCreationOptions.None)
{
new Thread(ThreadPoolTaskScheduler.s_longRunningThreadWork)
{
IsBackground = true
}.Start((object) task);
}
else
{
bool forceGlobal = (uint) (task.Options & TaskCreationOptions.PreferFairness) > 0U;
ThreadPool.UnsafeQueueCustomWorkItem((IThreadPoolWorkItem) task, forceGlobal);
}
}
public void Enqueue(IThreadPoolWorkItem callback, bool forceGlobal)
{
ThreadPoolWorkQueueThreadLocals queueThreadLocals = (ThreadPoolWorkQueueThreadLocals) null;
if (!forceGlobal)
queueThreadLocals = ThreadPoolWorkQueueThreadLocals.threadLocals;
if (this.loggingEnabled)
FrameworkEventSource.Log.ThreadPoolEnqueueWorkObject((object) callback);
if (queueThreadLocals != null)
{
queueThreadLocals.workStealingQueue.LocalPush(callback);
}
else
{
ThreadPoolWorkQueue.QueueSegment comparand = this.queueHead;
while (!comparand.TryEnqueue(callback))
{
Interlocked.CompareExchange<ThreadPoolWorkQueue.QueueSegment>(ref comparand.Next, new ThreadPoolWorkQueue.QueueSegment(), (ThreadPoolWorkQueue.QueueSegment) null);
for (; comparand.Next != null; comparand = this.queueHead)
Interlocked.CompareExchange<ThreadPoolWorkQueue.QueueSegment>(ref this.queueHead, comparand.Next, comparand);
}
}
this.EnsureThreadRequested();
}
internal volatile IThreadPoolWorkItem[] m_array = new IThreadPoolWorkItem[];
private SpinLock m_foreignLock = new SpinLock(false);
public void LocalPush(IThreadPoolWorkItem obj)
{
int num1 = this.m_tailIndex;
if (num1 == int.MaxValue)
{
bool lockTaken = false;
try
{
this.m_foreignLock.Enter(ref lockTaken);
if (this.m_tailIndex == int.MaxValue)
{
this.m_headIndex = this.m_headIndex & this.m_mask;
this.m_tailIndex = num1 = this.m_tailIndex & this.m_mask;
}
}
finally
{
if (lockTaken)
this.m_foreignLock.Exit(true);
}
}
if (num1 < this.m_headIndex + this.m_mask)
{
Volatile.Write<IThreadPoolWorkItem>(ref this.m_array[num1 & this.m_mask], obj);
this.m_tailIndex = num1 + ;
}
else
{
bool lockTaken = false;
try
{
this.m_foreignLock.Enter(ref lockTaken);
int num2 = this.m_headIndex;
int num3 = this.m_tailIndex - this.m_headIndex;
if (num3 >= this.m_mask)
{
IThreadPoolWorkItem[] threadPoolWorkItemArray = new IThreadPoolWorkItem[this.m_array.Length << ];
for (int index = ; index < this.m_array.Length; ++index)
threadPoolWorkItemArray[index] = this.m_array[index + num2 & this.m_mask];
this.m_array = threadPoolWorkItemArray;
this.m_headIndex = ;
this.m_tailIndex = num1 = num3;
this.m_mask = this.m_mask << | ;
}
Volatile.Write<IThreadPoolWorkItem>(ref this.m_array[num1 & this.m_mask], obj);
this.m_tailIndex = num1 + ;
}
finally
{
if (lockTaken)
this.m_foreignLock.Exit(false);
}
}
}
.NET Task揭秘(一)的更多相关文章
- 学习ASP.NET Web API框架揭秘之“HTTP方法重写”
最近在看老A的<ASP.NET Web API 框架揭秘>,这本书对于本人现阶段来说还是比较合适的(对于调用已经较为熟悉,用其开发过项目,但未深入理解过很多内容为何可以这样“调用”).看到 ...
- Spark Tungsten揭秘 Day3 内存分配和管理内幕
Spark Tungsten揭秘 Day3 内存分配和管理内幕 恭喜Spark2.0发布,今天会看一下2.0的源码. 今天会讲下Tungsten内存分配和管理的内幕.Tungsten想要工作,要有数据 ...
- Spark Streaming揭秘 Day30 集群模式下SparkStreaming日志分析
Spark Streaming揭秘 Day30 集群模式下SparkStreaming日志分析 今天通过集群运行模式观察.研究和透彻的刨析SparkStreaming的日志和web监控台. Day28 ...
- Spark Streaming揭秘 Day17 资源动态分配
Spark Streaming揭秘 Day17 资源动态分配 今天,让我们研究一下一个在Spark中非常重要的特性:资源动态分配. 为什么要动态分配?于Spark不断运行,对资源也有不小的消耗,在默认 ...
- Spark Streaming揭秘 Day4-事务一致性(Exactly one)
Spark Streaming揭秘 Day4 事务一致性Exactly one 引子 对于业务处理系统,事务的一致性非常的关键,事务一致性(Exactly one),简单来说,就是输入数据一定会被处理 ...
- ASP.NET Web API框架揭秘:路由系统的几个核心类型
ASP.NET Web API框架揭秘:路由系统的几个核心类型 虽然ASP.NET Web API框架采用与ASP.NET MVC框架类似的管道式设计,但是ASP.NET Web API管道的核心部分 ...
- 第四节:Task的启动的四种方式以及Task、TaskFactory的线程等待和线程延续的解决方案
一. 背景 揭秘: 在前面的章节介绍过,Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然也可以基本业务需要的多线程场景,但它们在多个线程的等待处理方面 ...
- 第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。
一. 整体说明 揭秘: 通过F12查看Task类的源码(详见下面的截图),发现Task类的构造函数有有一个参数为:TaskCreationOptions类型,本章节可以算作是一个扩展章节,主要就来研究 ...
- 第六节:深入研究Task实例方法ContinueWith的参数TaskContinuationOptions
一. 整体说明 揭秘: 该章节的性质和上一个章节类似,也是一个扩展的章节,主要来研究Task类下的实例方法ContinueWith中的参数TaskContinuationOptions. 通过F12查 ...
随机推荐
- Mono 3.2 上跑NUnit测试
NUnit是一款堪与JUnit齐名的开源的回归测试框架,供.net开发人员做单元测试之用,可以从www.nunit.org网站上免费获得,最新版本是2.5.Mono 3.2 源码安装的,在/usr/b ...
- .Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)
上一篇中说到了“泵”在编程中的作用以及一些具体用处,但没有实际demo,可能不好理解,这篇文章我分享一个UDP通信的demo,大概实现了类似“飞鸽传书”在局域网中文本消息和文件传输的功能.功能不全也不 ...
- iOS开发系列--C语言之构造类型
概述 在第一节中我们就提到C语言的构造类型,分为:数组.结构体.枚举.共用体,当然前面数组的内容已经说了很多了,这一节将会重点说一下其他三种类型. 结构体 枚举 共用体 结构体 数组中存储的是一系列相 ...
- Orchard 微软CMS项目介绍
我之前的项目中使用了Orchard, 它依据依赖注入的思想而做的模块化让我深深为之着迷,这里开始宣传一下这个架构. 包含的概念非常之多,我现在也不甚了解.Orchard就是自己想控制它改变它的话需要非 ...
- [SQLServer大对象]——FileTable从文件系统迁移文件
阅读导航 从文件系统中迁移文件到FileTable 批量加载文件到FileTable 如何批量加载文件到FileTable 通过博文[SQLServer大对象]——FileTable初体验,已经可以将 ...
- C语言 · 最小乘积(基本型)
问题描述 给两组数,各n个. 请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小.要求程序输出这个最小值. 例如两组数分别为:1 3 -5和-2 4 1 那么对应乘积取和的最小 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (12) -----第三章 查询之使用SQL语句
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-2使用原生SQL语句更新 问题 你想在实体框架中使用原生的SQL语句,来更新底层 ...
- 《Spark大数据处理》—— 读后总结
前几章 工作机制
- JQuery图片切换动画效果
由于博主我懒,所以页面画的比较粗糙,但是没关系,因为我主要讲的是如何实现图片动画切换. 思路:想必大家都逛过淘宝或者其他的一些网站,一般都会有图片动画切换的效果,那是怎样实现的呢?博主我呢,技术不是很 ...
- java线程 公平锁 ReentrantLock(boolean fair)
一.公平锁 1.为什么有公平锁 CPU在调度线程的时候是在等待队列里随机挑选一个线程,由于这种随机性所以是无法保证线程先到先得的(synchronized控制的锁就是这种非公平锁).但这样就会产生饥饿 ...