Task是.NET4.0加入的,跟线程池ThreadPool的功能类似,用Task开启新任务时,会从线程池中调用线程,而Thread每次实例化都会创建一个新的线程。任务(Task)是架构在线程之上的,也就是说任务最终还是要抛给线程(Thread)去执行。

1、首次构造一个Task对象时,他的状态是Created。
2、当任务启动时,他的状态变成WaitingToRun。
3、Task在一个线程上运行时,他的状态变成Running。
4、任务停止运行,等待他的任何子任务时,状态变成WaitingForChildrenToComplete。
5、任务完全结束时,它进入以下三个状态之一:RanToCompletion,Canceled或者Faulted。
6、一个Task<TResult>运行完成时,可通过Task<TResult>的Result属性来查询任务的结果,
7、一个Task或者Task<TResult>出错时,可以查询Task的Exception属性来获得任务抛出的未处理的异常,该属性总是返回一个AggregateException对象,他包含所有未处理的异常。
8、为简化代码,Task提供了几个只读的Boolean属性,IsCanceled,IsFaulted,IsCompleted。
9、注意,当Task处于RanToCompleted,Canceled或者Faulted状态时,IsCompleted返回True。
10、为了判断一个Task是否成功完成,最简单的方法是:if(task.Status == TaskStatus.RanToCompletion)。
11、task的ContinueWith方法用于在一个任务完成后发起一个新任务。

任务Task和线程Thread的区别:

static void Main(string[] args)
{
for (int i = ; i < ; i++)
{
new Thread(Run1).Start();
}
for (int i = ; i < ; i++)
{
Task.Run(() => { Run2(); });
}
}
static void Run1()
{
Console.WriteLine("Thread Id =" + Thread.CurrentThread.ManagedThreadId);
}
static void Run2()
{
Console.WriteLine("Task调用的Thread Id =" + Thread.CurrentThread.ManagedThreadId);
}

Task使用方法

创建Task有两种方式,一种是使用构造函数创建,另一种是使用 Task.Factory.StartNew 进行创建。如下代码所示

1.使用构造函数创建Task

  Task t1 = new Task(MyMethod);

2.使用Task.Factory.StartNew 进行创建Task

  Task t1 = Task.Factory.StartNew(MyMethod);

多任务

public void test()
{
Task[] tasks = new Task[];
for (int i = ; i < ; i++)
{
if (i % == )
{
tasks[i] = new Task(test2, (object)i);//传参,必须是obj
}
else
{
tasks[i] = new Task(test1);
}
tasks[i].Start();
}
Task.WaitAll(tasks);//等待所有线程执行完成后才会继续往下执行
     //Task.WaitAll(tasks,5000);//最多等待5秒
        Response.Write("执行完成");
}
private void test1()
{
//do
}
private void test2(object ourl)
{
//do
}

连续任务

static void DownLoad(object str)
{
//下载文件
}
static void ReadNews(Task obj)
{
//读取文件
}
static void Main(string[] args)
{
Task task = new Task(DownLoad, "人民日报");
Task task2 = task.ContinueWith(ReadNews);
task.Start();
//DownLoad执行完才执行ReadNews
}

Task返回值

Task<string> t1 = Task.Factory.StartNew(() => "测试");
t1.Wait();
Console.WriteLine(t1.Result);
Console.ReadLine();
//返回值可以是任意的类型

Task线程池最大数量

这个TaskScheduler是微软开源的一个任务调度器

LimitedConcurrencyLevelTaskScheduler.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Threading; /// <summary>
///LimitedConcurrencyLevelTaskScheduler 的摘要说明
/// </summary>
public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{
// Indicates whether the current thread is processing work items.
[ThreadStatic]
private static bool _currentThreadIsProcessingItems; // The list of tasks to be executed
private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks) // The maximum concurrency level allowed by this scheduler.
private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items.
private int _delegatesQueuedOrRunning = ; // Creates a new instance with the specified degree of parallelism.
public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
{
if (maxDegreeOfParallelism < ) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
_maxDegreeOfParallelism = maxDegreeOfParallelism;
} // Queues a task to the scheduler.
protected sealed override void QueueTask(Task task)
{
// Add the task to the list of tasks to be processed. If there aren't enough
// delegates currently queued or running to process tasks, schedule another.
lock (_tasks)
{
_tasks.AddLast(task);
if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
{
++_delegatesQueuedOrRunning;
NotifyThreadPoolOfPendingWork();
}
}
} // Inform the ThreadPool that there's work to be executed for this scheduler.
private void NotifyThreadPoolOfPendingWork()
{
ThreadPool.UnsafeQueueUserWorkItem(_ =>
{
// Note that the current thread is now processing work items.
// This is necessary to enable inlining of tasks into this thread.
_currentThreadIsProcessingItems = true;
try
{
// Process all available items in the queue.
while (true)
{
Task item;
lock (_tasks)
{
// When there are no more items to be processed,
// note that we're done processing, and get out.
if (_tasks.Count == )
{
--_delegatesQueuedOrRunning;
break;
} // Get the next item from the queue
item = _tasks.First.Value;
_tasks.RemoveFirst();
} // Execute the task we pulled out of the queue
base.TryExecuteTask(item);
}
}
// We're done processing items on the current thread
finally { _currentThreadIsProcessingItems = false; }
}, null);
} // Attempts to execute the specified task on the current thread.
protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
// If this thread isn't already processing a task, we don't support inlining
if (!_currentThreadIsProcessingItems) return false; // If the task was previously queued, remove it from the queue
if (taskWasPreviouslyQueued)
// Try to run the task.
if (TryDequeue(task))
return base.TryExecuteTask(task);
else
return false;
else
return base.TryExecuteTask(task);
} // Attempt to remove a previously scheduled task from the scheduler.
protected sealed override bool TryDequeue(Task task)
{
lock (_tasks) return _tasks.Remove(task);
} // Gets the maximum concurrency level supported by this scheduler.
public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } } // Gets an enumerable of the tasks currently scheduled on this scheduler.
protected sealed override IEnumerable<Task> GetScheduledTasks()
{
bool lockTaken = false;
try
{
Monitor.TryEnter(_tasks, ref lockTaken);
if (lockTaken) return _tasks;
else throw new NotSupportedException();
}
finally
{
if (lockTaken) Monitor.Exit(_tasks);
}
}
}

使用方法

控制多线程数量,并实时输出已完成任务数量

protected void Page_Load(object sender, EventArgs e)
{
Response.Write("<script type=\"text/javascript\">function load(i) {document.getElementById(\"now\").innerHTML = i;}</script>");
Response.Write("<span id='now'>0</span>/<span id='sum'>" + arr.Length + "</span>");
Response.Flush(); //设置最大线程数为5
var scheduler = new LimitedConcurrencyLevelTaskScheduler();
var Factory = new TaskFactory(scheduler);
Task[] tasks = new Task[];
int res = ;
for (int i = ; i < ; i++)
{
Task tk = Factory.StartNew(() => downFile((object)i));
tk.ContinueWith(t =>
{
res++;
Response.Write("<script>load(" + res.ToString() + ")</script>");
Response.Flush();
});
tasks[i] = tk; }
Task.WaitAll(tasks);
Response.Write("完成");
}
private void downFile(object oid)
{
string iid= (string)id;
//do... }

Task使用过程中遇到的坑

使用过程中发现有的task任务不执行,经过长时间调试发现在task调用的方法里很多C#方法不可用,

例如HttpContext.Current.Request.Url、HttpContext.Current.Server.MapPath等方法不可用,真是坑

//end

Asp.Net任务Task和线程Thread的更多相关文章

  1. C#中假设正确使用线程Task类和Thread类

    C#中使用线程Task类和Thread类小结 刚接触C#3个月左右.原先一直使用C++开发.由于公司的须要,所地採用C#开发.主要是控制设备的实时性操作,此为背景. 对于C#中的Task和Thread ...

  2. Activity, Service,Task, Process and Thread之间的关系

    Activity, Service,Task, Process and Thread之间到底是什么关系呢? 首先我们来看下Task的定义,Google是这样定义Task的:a task is what ...

  3. Task.Delay() 和 Thread.Sleep() 区别

    1.Thread.Sleep 是同步延迟,Task.Delay异步延迟. 2.Thread.Sleep 会阻塞线程,Task.Delay不会. 3.Thread.Sleep不能取消,Task.Dela ...

  4. Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别

    Task C# 多线程和异步模型 TPL模型   Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...

  5. task.delay 和 thread.sleep

    1.Thread.Sleep 是同步延迟. Task.Delay异步延迟. 2.Thread.Sleep 会阻塞线程,Task.Delay不会. 3.Thread.Sleep不能取消,Task.Del ...

  6. Lua 学习笔记(九)协同程序(线程thread)

    协同程序与线程thread差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和命令指针,同时又与其他协同程序共享全局变量和其他大部分东西.从概念上讲线程与协同程序的主要区别在于,一个具有多个线程的 ...

  7. java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍

    (原创,转载请说明出处!谢谢--http://www.cnblogs.com/linguanh/) 此文目的为了帮助大家较全面.通俗地了解线程 Thread 相关基础知识! 目录: --线程的创建: ...

  8. Android 线程Thread的2种实现方法

    在讲解之前有以下三点要说明: 1.在Android中有两种实现线程Thread的方法: ①扩展java.long.Thread类: ②实现Runnable()接口: 2.Thread类是线程类,它有两 ...

  9. 线程(thread)

    线程(thread): 现代操作系统引入进程概念,为了并发(行)任务 1.进程之间的这种切换代价很高 2.通信方式的代价也很大基本概念: 1.线程是比进程更小的资源单位,它是进程中的一个执行路线(分支 ...

随机推荐

  1. vim编辑

    vim 重点在于光标的移动,模式的切换,删除,查找,替换,复制,黏贴,撤销命令的使用 vim的三种模式:命令模式(打开文件默认进入此模式)编辑模式(输入模式)末行模式(按:键进入,只能从命令模式下按键 ...

  2. 如何基于asp.net core的Identity框架在mysql上作身份验证处理

    首先了解这个概念,我一开始也是理解和掌握基本的概念,再去做程序的开发.Identity框架是微软自己提供,基于.net core平台,可拓展.轻量 级.面向多个数据库的身份验证框架.IdentityS ...

  3. 使用Log4j日志处理

    Springboot日志默认使用的是logback,本文将介绍将springboot项目日志修改为log4j. 首先要将默认的日志依赖排除,然后引用log4j,pom文件代码如下: <?xml ...

  4. 转:自旋锁(spinlock)

    自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名. 由于 ...

  5. skatebroads

    skateboardsn.滑板( skateboard的名词复数 ) == skateboard英 [ˈskeɪtbɔ:d]  . 斯给特博得. 美 [ˈskeɪtbɔ:rd] n.滑板复数: ska ...

  6. 多角度对比 ES5与ES6的区别

    ES5与ES6的对比不同点整理 本文关键词:ES6,javascript, 1.Default Parameters(默认参数) es6之前,定义默认参数的方法是在一个方法内部定义 var link ...

  7. [NOI2014]起床困难综合征

    Description: 有n扇门,每扇门上有一个位运算符(&,|,^) 和一个权值,要求合理的选择一个不超过m的数,使其按顺序经过这些门的运算后最大 Hint: \(n \le 10^5\) ...

  8. C++程序设计方法4:模板特化

    模板参数的具体化/特殊化 有时,有些类型不适用,则需要对模板进行特殊化处理,这称为“模板特化” 对函数模板,如果有多个模板参数,则特化时必须提供所有参数的特例类型,不能部分特化: 如: char *s ...

  9. JS 之 script标签

    1.script标签 1.js代码的解析(包括下载js文件)会阻塞页面加载 2.当js文件放在头部,页面必须等所有js代码都被下载,解析和执行完成后才开始呈现页面内容(遇到body标签才呈现),对于那 ...

  10. redis:order set有序集合类型的操作(有序集合)

    1. order set有序集合类型的操作(有序集合) 有序集合是在无序集合的基础上加了一个排序的依据,这个排序依据叫score,因此声明一个集合为有序集合的时候要加上score(作为排序的依据) 1 ...