• C# 应用


    1. 与 Task.Run() 的区别;

    先看一下源码:

    public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable
    {
        public static Task Run(Action action)
        {
        	StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
        	return InternalStartNew(null, action, null, 
        	                        default(CancellationToken),
        	                        TaskScheduler.Default,
        	                        TaskCreationOptions.DenyChildAttach,
        	                        InternalTaskOptions.None, 
        	                        ref stackMark);
        }
        
        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(needsProtection: false);
            return task;
        }
        ...
    }
    
    
    public class TaskFactory
    {
        public Task StartNew(Action action)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            Task internalCurrent = Task.InternalCurrent;
            return Task.InternalStartNew(internalCurrent, action, null,
                                         m_defaultCancellationToken,
                                         GetDefaultScheduler(internalCurrent),
                                         m_defaultCreationOptions,
                                         InternalTaskOptions.None,
                                         ref stackMark);
        }
        
        public Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return Task.InternalStartNew(Task.InternalCurrentIfAttached(creationOptions), action, null, 
                                         cancellationToken, 
                                         scheduler, 
                                         creationOptions, 
                                         InternalTaskOptions.None, 
                                         ref stackMark);
        }
        ...
    }
    	
    
    

    Task.Run() 是 .Net Framework 4.5 之后提出的,Task.Factory.StartNew() 可以使用更多的参数,可以认为 Task.Run 是简化版的使用,而 Task.Factory.StartNew() 主要用于需要指定该线程是长期占用的,否则用 task.Run

    Task.Factory.StartNew(()=>{
        ...
    }, TaskCreationOptions.LongRunning
    );
    
    TaskCreationOptions.LongRunning 它会向 System.Threading.Tasks.TaskScheduler提示,
    过度订阅可能是合理的。 
    可以通过过度订阅创建比可用硬件线程数更多的线程。
    它还将提示任务计划程序:该任务需要附加线程,以使任务不阻塞本地线程池队列中其他线程或工作项的向前推动。
    

    2. CancellationToken 入参:取消令牌;

    可参考 https://www.cnblogs.com/MichaelLoveSna/p/14507488.html

    3. TaskCreationOptions 入参:父子之间的依附态度等;

    TaskCreationOptions.LongRunning;
    TaskCreationOptions.AttachedToParent;
    TaskCreationOptions.DenyChildAttach;
    
    TaskCreationOptions.AttachedToParent 表示该 Task 可以依附在父 Task 上,
    当父 Task wait 的时候,会等待该 Task 执行完毕;  
    TaskCreationOptions.DenyChildAttach 就是为了避免子 Task 设置 TaskCreationOptions.AttachedToParent,
    强行拒绝依附。
    这一对有点像,儿子:爸,等我;父亲说:别闹,我没有你这个儿子。
    

    4. TaskScheduler :线程调度

    TaskScheduler.Default 线程池的线程
    TaskScheduler.FromCurrentSynchronizationContext() 用了运行在一个与当前函数相同的线程中(也就是UI线程中,除非是 Task 的 Task)
    这个描述可能听起来有点抽象,需要意会一下。
    
  • 相关阅读:
    解决maven构建webapp index.jsp报错问题
    Maven入门介绍
    Linux常用命令的解释
    linux怎么查看一个文件夹的大小
    EPEL源-是什么全称
    nginx+php-fpm配置后页面显示空白的解决方法(yum形式的安装)
    配置新服务器 的一些 依赖库 php mysql nginx
    服务器 CentOS上yum安装Nginx服务
    Java File创建新目录和文件
    struts2的文件上传
  • 原文地址:https://www.cnblogs.com/MichaelLoveSna/p/14507487.html
Copyright © 2020-2023  润新知