一、Task关键字解释

Task 类的表示的单个操作不会返回一个值,通常以异步方式执行。 Task 对象是一种的中心思想 基于任务的异步编程模式 首次引入.NET Framework 4 中。 因为由执行工作 Task 对象通常上异步执行一个线程池线程而不是以同步方式在主应用程序线程中,您可以使用 Status 属性,以及 IsCanceled, , IsCompleted, ,和 IsFaulted 属性,以此来确定任务的状态。 大多数情况下,lambda 表达式用于指定的任务是执行的工作。可以说在某种程度上类似于线程池,但比线程池更容易使用。

需要用到的程序集

mscorlib(在 mscorlib.dll 中)
System.Threading.Tasks(在 System.Threading.Tasks.dll 中)

二、Task和ThreadPool

Task是在ThreadPool的基础上推出的,ThreadPool中有若干数量的线程,如果有任务需要处理时,会从线程池中获取一个空闲的线程来执行任务,任务执行完毕后线程不会销毁,而是被线程池回收以供后续任务使用。当线程池中所有的线程都在忙碌时,又有新任务要处理时,线程池才会新建一个线程来处理该任务,如果线程数量达到设置的最大值,任务会排队,等待其他任务释放线程后再执行。线程池能减少线程的创建,节省开销。

看下面代码

    class Program
{
static void Main(string[] args)
{
for (int i = ; i <= ; i++)
{
//ThreadPool执行任务
ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
{
Thread.Sleep();
Console.WriteLine($"第{obj}个执行任务");
}), i);
}
Console.ReadKey();
}
}
}

结果是:

相对于Thread优势:

1、代码简单

2、减少不必要的创建,降低开销

自身缺点:

ThreadPool不能控制线程的执行顺序,我们也不能获取线程池内线程取消/异常/完成的通知,即我们不能有效监控和控制线程池中的线程。

三、Task的使用

1、类厂调用

          Task t=  Task.Factory.StartNew(() =>
{
for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from lambda:" + i);
}
}); t.Wait(); for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from main:"+i);
}

一般的,如果我们不需要得到lambda的返回值,也不需要控制它和主线程中的线程关系,只要求它和主线程同时高效执行Task.Factory.StartNew就好,如果需要阻塞主线程,则需要给任务一个引用t,并在需要的地方调用阻塞方法Wait,WaitAll是针对任务链

2、Task的构造函数初始化 (可以添加第二个参数附加信息)

需要调用task,开始执行任务

          Task t=  new Task(() =>
{
for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from lambda:" + i);
}
}); t.Start(); for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from main:"+i);
} t.Wait();

3、Run

          Task t=  Task.Run(() =>
{
for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from lambda:" + i);
}
}); for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from main:"+i);
} t.Wait();

四、同步执行

Task提供了  task.RunSynchronously()用于同步执行Task任务

          Task t=  new Task(() =>
{
for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from lambda:" + i);
}
}); t.RunSynchronously(); for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from main:"+i);
} t.Wait();

五、有返回值

            Func<string> func = ()=>
{
System.Threading.Thread.Sleep();
return "from func";
}; Task<string> t= new Task<string>(func); t.Start(); for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
Console.WriteLine("from main:"+i);
} t.Wait(); Console.WriteLine(t.Result);

调用t.result的时候,调用线程会阻塞

六、Task任务的阻塞(Wait/WaitAll/WaitAny)

 Thread的Join方法可以阻塞调用线程,但是有一些弊端:①如果我们要实现很多线程的阻塞时,每个线程都要调用一次Join方法;②如果我们想让所有的线程执行完毕(或者任一线程执行完毕)时,立即解除阻塞,使用Join方法不容易实现。Task提供了  Wait/WaitAny/WaitAll  方法,可以更方便地控制线程阻塞。

task.Wait()  表示等待task执行完毕,功能类似于thead.Join();  Task.WaitAll(Task[] tasks)  表示只有所有的task都执行完成了再解除阻塞;  Task.WaitAny(Task[] tasks) 表示只要有一个task执行完毕就解除阻塞

如果将栗子中的WaitAll换成WaitAny,那么任一task执行完毕就会解除线程阻塞,执行结果是:先打印【线程1执行完毕】,然后打印【主线程执行完毕】,最后打印【线程2执行完毕】

七、Task任务的取消

1 Thread取消任务执行

在Task前我们执行任务采用的是Thread,Thread如何取消任务,可以建立一个key

 
        static void Main(string[] args)
{
bool key= false;
int index = 0;
Thread t= new Thread(() =>
{
while (!key)
{
Thread.Sleep(1000);
Console.WriteLine("thread operating....");
}
});
t.Start();
//五秒后取消任务执行
Thread.Sleep(5000);
key= true;
Console.ReadKey();
}
 

  Task中有一个专门的类 CancellationTokenSource  来取消任务执行,还是使用上边的例子,我们修改代码如下,程序运行的效果不变。

        static void Main(string[] args)
{
CancellationTokenSource source = new CancellationTokenSource();
int index = 0;
//开启一个task执行任务
Task task= new Task(() =>
{
while (!source.IsCancellationRequested)
{
Thread.Sleep(1000);
Console.WriteLine("task operating...");
}
});
task.Start();
//五秒后取消任务执行
Thread.Sleep(5000);
//source.Cancel()方法请求取消任务,IsCancellationRequested会变成true
source.Cancel();
Console.ReadKey();
}
 

有疑问请加qq群:568055323

C#深度学习のTask(基于任务的异步模型)的更多相关文章

  1. 深度学习之Attention Model(注意力模型)

    1.Attention Model 概述 深度学习里的Attention model其实模拟的是人脑的注意力模型,举个例子来说,当我们观赏一幅画时,虽然我们可以看到整幅画的全貌,但是在我们深入仔细地观 ...

  2. 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 ...

  3. .NET - 基于事件的异步模型

    注:这是大概四年前写的文章了.而且我离开.net领域也有四年多了.本来不想再发表,但是这实际上是Active Object模式在.net中的一种重要实现方法,因此我把它掏出来发布一下.如果该模型有新的 ...

  4. [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型

    [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型 目录 [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型 0x00 摘要 0x01 前言 1.1 改 ...

  5. 深度学习基础-基于Numpy的卷积神经网络(CNN)实现

    本文是深度学习入门: 基于Python的实现.神经网络与深度学习(NNDL)以及动手学深度学习的读书笔记.本文将介绍基于Numpy的卷积神经网络(Convolutional Networks,CNN) ...

  6. 深度学习基础-基于Numpy的多层前馈神经网络(FFN)的构建和反向传播训练

    本文是深度学习入门: 基于Python的实现.神经网络与深度学习(NNDL)以及花书的读书笔记.本文将以多分类任务为例,介绍多层的前馈神经网络(Feed Forward Networks,FFN)加上 ...

  7. 深度学习基础-基于Numpy的感知机Perception构建和训练

    1. 感知机模型   感知机Perception是一个线性的分类器,其只适用于线性可分的数据.          f(x) = sign(w.x + b) 其试图在所有线性可分超平面构成的假设空间中找 ...

  8. 【机器学习PAI实践十】深度学习Caffe框架实现图像分类的模型训练

    背景 我们在之前的文章中介绍过如何通过PAI内置的TensorFlow框架实验基于Cifar10的图像分类,文章链接:https://yq.aliyun.com/articles/72841.使用Te ...

  9. Task C# 多线程和异步模型 TPL模型

    Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task TaskCompletionSource 更通用, ...

随机推荐

  1. sqlserver 2008R2新建数据库时报错,提示无法获得数据库"model"上的排它锁

    刚新装了个sqlserver2008 R2,在建立数据库时候报错,提示无法获得数据库"model"上的排它锁.解决办法如下: 打开查询页面,执行下面的语句即可. use maste ...

  2. Laravel 系列入门教程(一)【最适合中国人的 Laravel 教程】

    热烈庆祝 Laravel 5.5 LTS 发布! 实际上 Laravel 上一个 LTS 选择 5.1 是非常不明智的,因为 5.2 增加了许许多多优秀的特性.现在好了,大家都用最新的长期支持版本 5 ...

  3. ChartControl ViewType.Pie3D 用法测试

    效果图一. public partial class Form3 : Form { public Form3() { InitializeComponent(); } private void For ...

  4. [代码笔记]VUE路由根据返回状态判断添加响应拦截器

    //返回状态判断(添加响应拦截器) Axios.interceptors.response.use( res => { //对响应数据做些事 if (res.data && !r ...

  5. 2018-08-16 中文代码之Spring Boot添加基本日志

    之前中文代码之Spring Boot实现简单REST服务的演示服务不知为何中止. 新开issue: 演示服务中止 · Issue #2 · program-in-chinese/programming ...

  6. 一文读懂机器学习大杀器XGBoost原理

    http://blog.itpub.net/31542119/viewspace-2199549/ XGBoost是boosting算法的其中一种.Boosting算法的思想是将许多弱分类器集成在一起 ...

  7. iOS------Xcode 的clang 扫描器可以检测出所有的内存泄露吗

    在苹果没有出ARC(自动内存管理机制)时,我们几乎有一半的开发时间都耗费在这么管理内存上.后来苹果很人性的出了ARC,虽然在很大程度上,帮助我们开发者节省了精力和时间.但是我们在开发过程中,由于种种原 ...

  8. mybatis的三种批量插入以及次效率比较

    1.表结构 CREATE TABLE `t_user` ( `id` varchar(32) CHARACTER SET utf8 NOT NULL COMMENT '主键', `name` varc ...

  9. phpstudy 上怎么运行 thinkPHP ?

    最近在学习 thinkPHP ,但是本地使用的是 phpstudy ,就想在 phpstudy 中使用 thinkPHP ,这样我的环境就不用再改变也可以学习. 首先,先要 下载 thinkPHP , ...

  10. 使用VSTS的Git进行版本控制(三)——评审历史记录

    使用VSTS的Git进行版本控制(三)--评审历史记录 Git使用存储在每个提交中的父引用信息来管理开发的完整历史记录.评审该提交历史记录,能够找出文件更改的时间,并确定代码版本之间的差异. Git使 ...