C#深度学习のTask(基于任务的异步模型)
一、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(基于任务的异步模型)的更多相关文章
- 深度学习之Attention Model(注意力模型)
1.Attention Model 概述 深度学习里的Attention model其实模拟的是人脑的注意力模型,举个例子来说,当我们观赏一幅画时,虽然我们可以看到整幅画的全貌,但是在我们深入仔细地观 ...
- 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 ...
- .NET - 基于事件的异步模型
注:这是大概四年前写的文章了.而且我离开.net领域也有四年多了.本来不想再发表,但是这实际上是Active Object模式在.net中的一种重要实现方法,因此我把它掏出来发布一下.如果该模型有新的 ...
- [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型
[源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型 目录 [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型 0x00 摘要 0x01 前言 1.1 改 ...
- 深度学习基础-基于Numpy的卷积神经网络(CNN)实现
本文是深度学习入门: 基于Python的实现.神经网络与深度学习(NNDL)以及动手学深度学习的读书笔记.本文将介绍基于Numpy的卷积神经网络(Convolutional Networks,CNN) ...
- 深度学习基础-基于Numpy的多层前馈神经网络(FFN)的构建和反向传播训练
本文是深度学习入门: 基于Python的实现.神经网络与深度学习(NNDL)以及花书的读书笔记.本文将以多分类任务为例,介绍多层的前馈神经网络(Feed Forward Networks,FFN)加上 ...
- 深度学习基础-基于Numpy的感知机Perception构建和训练
1. 感知机模型 感知机Perception是一个线性的分类器,其只适用于线性可分的数据. f(x) = sign(w.x + b) 其试图在所有线性可分超平面构成的假设空间中找 ...
- 【机器学习PAI实践十】深度学习Caffe框架实现图像分类的模型训练
背景 我们在之前的文章中介绍过如何通过PAI内置的TensorFlow框架实验基于Cifar10的图像分类,文章链接:https://yq.aliyun.com/articles/72841.使用Te ...
- Task C# 多线程和异步模型 TPL模型
Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task TaskCompletionSource 更通用, ...
随机推荐
- C# 获取当前屏幕的宽高和位置
上一篇博客<C# 获取当前屏幕DPI>,介绍了如何获取当前屏幕的DPI设置 本章主要介绍如何获取当前窗口所在屏幕的信息 当前屏幕信息 如果当前是单屏幕,可以直接获取主屏幕 var prim ...
- Wpf学习20180605
Windows Presentation Foundation 窗口展示框架 WPF. 与winform界面程序比较,我认为最大的区别是‘与分辨率无关’这个特性. 传统winform程序在低分辨率的电 ...
- Transact-SQL解析和基本的实用语句
SQL语言 DDL(数据定义语句) DML(数据操作语句) DCL(数据控制语句) DDL 数据定义 操作对象 操作方式 创建 删除 修改 模式 CREATE SCHEMA DROP SCHEMA 表 ...
- Spring Boot从入门到精通之:一、Spring Boot简介及快速入门
Spring Boot Spring Boot 简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来 ...
- Flask 系列之 FlaskForm
通过使用 FlaskForm ,可以方便快捷的实现表单处理. 说明 操作系统:Windows 10 Python 版本:3.7x 虚拟环境管理器:virtualenv 代码编辑器:VS Code 实验 ...
- 用函数式编程对JavaScript进行断舍离
译者按: 当从业20的JavaScript老司机学会函数式编程时,他扔掉了90%的特性,也不用面向对象了,最后发现了真爱啊!!! 原文: How I rediscovered my love for ...
- VUE 利用webpack 给生产环境和发布环境配置不同的接口地址
第一步,分别设置不同的接口地址 首先,我们分别找到下面的文件: /config/dev.env.js /config/prod.env.js 其实,这两个文件就是针对生产环境和发布环境设置不同参数的文 ...
- matlab练习程序(波纹扭曲)
其实就是用sin或cos对x,y坐标进行变换,处理的时候依然是反向变换. 类似的,用不同的函数能得到不同的扭曲效果,比如log,1/x,exp等等. 效果如下: 代码如下(还给出了如何生成gif图片的 ...
- codeforces 735C Tennis Championship(贪心+递推)
Tennis Championship 题目链接:http://codeforces.com/problemset/problem/735/C ——每天在线,欢迎留言谈论. 题目大意: 给你一个 n ...
- Scala并发编程【快速入门】
1.简介 Scala的actor提供了一种基于事件的轻量级线程.只要使用scala.actors.Actor伴生对象的actor()方法,就可以创建一个actor.它接受一个函数值/闭包做参数,一创建 ...