Task+ConcurrentQueue多线程编程
队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。
ConcurrentQueue<T>队列是一个高效的线程安全的队列,是.Net Framework 4.0,System.Collections.Concurrent命名空间下的一个数据结构。
Task是在ThreadPool的基础上推出的,我们知道了ThreadPool的弊端:我们不能控制线程池中线程的执行顺序,也不能获取线程池内线程取消/异常/完成的通知。net4.0在ThreadPool的基础上推出了Task,Task拥有线程池的优点,同时也解决了使用线程池不易控制的弊端。
下面我们来看下Task+ConcurrentQueue实现多线程编程
1、定义最大线程数, 一般和本机的cpu 有关
/// <summary>
/// 线程总数
/// </summary>
private int threadNum = Convert.ToInt32(ConfigurationManager.AppSettings["ThreadNum"]);
ConcurrentQueue队列
/// <summary>
/// 队列
/// </summary>
private ConcurrentQueue<AssetRepayment> queues = new ConcurrentQueue<AssetRepayment>();
2、接下来 我们把业务数据取出来,加到定义的 queues.Enqueue(l);
var dt = DateTime.Now.Date;
var list = AssetRepayService.GetRepayments().Where(o => o.AssetRepayStatus == AssetRepayStatus.NoSend && o.PlanRepaymentDate == dt && o.AssetRepayMode == AssetRepayMode.Withholding);
int count = list.Count();
if (count == 0)
{
LogHelper.WriteFatal("代扣充值-没有可执行的数据");
return;
}
totalCount = count;
int allpage = count / 200 + (count % 200 == 0 ? 0 : 1);
int page = 0;
LogHelper.WriteFatal("代扣充值-可执行的数据:" + count + "条,页数:"+ allpage); do
{
LogHelper.WriteFatal("代扣充值-第:" + page + "页"); var ll = list.OrderBy(o=>o.Id).Skip(page++ * 200).Take(200).ToList();
foreach (var l in ll)
{
queues.Enqueue(l);
}
}
while (page < allpage);
3、等数据全部加载到queues,我们接着下一步
List<Task> tasks = new List<Task>();
for (int i = 0; i < threadNum; i++)
{
var task = Task.Run(() =>
{
Process();
});
tasks.Add(task);
}
var taskList = Task.Factory.ContinueWhenAll(tasks.ToArray(), (ts) =>
{
});
taskList.Wait();
利用Task 处理数据
这里需要注意的是
var taskList = Task.Factory.ContinueWhenAll(tasks.ToArray(), (ts) =>
{
});
taskList.Wait();
这个代表开始执行线程并且需要全部完成 才会退出 ContinueWhenAll
4 接下去我们看下处理程序怎么消费数据
从队列取数据
var currentIndex = Interlocked.Increment(ref index);
AssetRepayment repayId = null;
var isExit = queues.TryDequeue(out repayId);
if (!isExit)
{
break;
}
有数据的话 往下走 执行我们要的业务逻辑
var service = context.GetService<IDeTransactionService>();
service.SubDeTransaction(repayId); LogHelper.WriteFatal(string.Format("代扣充值 共{0}条 当前第{1}条", totalCount, currentIndex));
完整处理方法如下
private void Process()
{
using (var context = new MefContext())
{
while (true)
{
var currentIndex = Interlocked.Increment(ref index);
AssetRepayment repayId = null;
var isExit = queues.TryDequeue(out repayId);
if (!isExit)
{
break;
}
try
{
var service = context.GetService<IDeTransactionService>();
service.SubDeTransaction(repayId); LogHelper.WriteFatal(string.Format("代扣充值 共{0}条 当前第{1}条", totalCount, currentIndex));
}
catch (Exception ex)
{
LogHelper.WriteError("代扣充值-", ex);
}
}
}
}
到此为止,我们实现了 Task+ConcurrentQueue多线程编程。
完整代码块
链接:https://pan.baidu.com/s/1jgpafTFssiVLmZhDe1CgYQ
提取码:erib
Task+ConcurrentQueue多线程编程的更多相关文章
- 5天玩转C#并行和多线程编程 —— 第四天 Task进阶
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...
- 5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...
- Scalaz(45)- concurrency :Task-函数式多线程编程核心配件
我们在上一节讨论了scalaz Future,我们说它是一个不完善的类型,最起码没有完整的异常处理机制,只能用在构建类库之类的内部环境.如果scalaz在Future类定义中增加异常处理工具的话,用户 ...
- 新手浅谈Task异步编程和Thread多线程编程
初学Task的时候上网搜索,看到很多文章的标题都是task取代thread等等相关,我也一直以为task和thread是一类,其实task是.net4.0提出的异步编程,在之前.net1.0有dele ...
- C#多线程编程(1)--线程,线程池和Task
新开了一个多线程编程系列,该系列主要讲解C#中的多线程编程. 利用多线程的目的有2个: 一是防止UI线程被耗时的程序占用,导致界面卡顿:二是能够利用多核CPU的资源,提高运行效率. 我没有进行很 ...
- 转载 .Net多线程编程—任务Task https://www.cnblogs.com/hdwgxz/p/6258014.html
.Net多线程编程—任务Task 1 System.Threading.Tasks.Task简介 一个Task表示一个异步操作,Task的创建和执行是独立的. 只读属性: 返回值 名称 说明 ob ...
- .NET 4中的多线程编程之一:使用Task(转载)
原文地址:http://www.cnblogs.com/yinzixin/archive/2011/11/04/2235233.html .NET 4为了简化多线程编程,提供了System.Threa ...
- 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天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...
随机推荐
- 关于wlw连接wordpress的问题
前几天搭建好wordpress博客网站后,一直想和博客园一样,使用wlw发布文章.无奈遇到了难题,一直没有办法解决. 今天我看到一篇博客,遇到问题和我类似:尝试连接到您的日志时出错:基础连接已经关闭: ...
- 【机器学*】k*邻算法-02
k邻*算法具体应用:2-2约会网站配对 心得体会: 1.对所有特征值进行归一化处理:将特征值单位带来的距离影响消除,使所有特征同权重--然后对不同的特征进行加权2.对于相互独立的特征,可以通过建立(特 ...
- HTML网页设计基础笔记 • 【第1章 HTML5基础】
全部章节 >>>> 本章目录 1.1 HTML介绍及开发工具 1.1.1 HTML 的基本概念 1.1.2 网页 1.1.3 Web 标准 1.1.4 HTML5 与移动互 ...
- versions-maven-plugin插件批量修改版本号
1.简介 versions-maven-plugin插件可以管理项目版本, 特别是当Maven工程项目中有大量子模块时, 可以批量修改pom版本号, 插件会把父模块更新到指定版本号, 然后更新子模块版 ...
- spring cloud --- config 从git 获取文件【 可能是yml或 properties】遇到有相同字段的取值规则
spring boot 1.5.9.RELEASE spring cloud Dalston.SR1 1.前言 昨天做了 spring cloud config 配置中心 获取存在gi ...
- Spring cloud 框架 --- Eureka 心得
spring boot 1.5.9.RELEASE spring cloud Dalston.SR1 1.前言 (1)接触了spring cloud 框架 ,首先要知道Eureka是什 ...
- Go语言命名规范
一.变量命名规范 变量命名一般采用驼峰式,当遇到特有名词(缩写或简称,如DNS)的时候,特有名词根据是否私有全部大写或小写.例子: var apiClient var URLString 二.常量命名 ...
- 小程序canvas绘制纯色圆角区域 setdata数组某一项
小程序canvas绘制纯色圆角区域: //方法: roundRectPath:function(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x ...
- Maven插件开发教程
Maven是一个一个优秀的项目管理开源框架,其插件机制为其功能扩展提供了非常大的便捷性.大多数情况下,我们不需要自己开发Maven插件,因为Maven本身提供了很多便捷的官方插件.但是对于某些特殊场景 ...
- winform创建桌面快捷方式
//引用IWshRuntimeLibrary COM组件-Windows Script Host Object Model /// <summary> /// 创建快捷方式的类 /// & ...