C# 线程--第四线程实例
概述
在前面几节中和大家分享了线程的一些基础使用方法,本章结合之前的分享来编写一些日常开发中应用实例,和编写多线程时一些注意点。如大家有好的实例也欢迎分享..
应用实例
应用:定时任务程序
场景:系统中常常会有一些需要定时去循环执行的存储过程或方法等,这时就出现了定时任务小程序。
模型:查询需定时执行的计划任务-->插入线程池-->执行任务
static void MainMethod()
{
Thread thead; thead = new Thread(QueryTask);
thead.IsBackground = true;
thead.Start(); Console.Read();
} /// <summary>
/// 查询计划任务
/// </summary>
static void QueryTask()
{
TaskModel todo_taskModel;
while (true)
{
int count = new Random().Next(, ); //模拟产生任务记录数
for (int i = ; i < count; i++)
{
todo_taskModel = new TaskModel() { TaskID = i, ITime = DateTime.Now };
ThreadPool.QueueUserWorkItem(InvokeThreadMethod, todo_taskModel);
} Thread.Sleep(); //30s循环一次
}
} /// <summary>
/// 完成计划任务
/// </summary>
/// <param name="taskModel"></param>
static void InvokeThreadMethod(object taskModel)
{
TaskModel model = (TaskModel)taskModel; Console.WriteLine("执行任务ID:{0}......执行完成.{1}", model.TaskID, model.ITime);
} /// <summary>
/// 任务实体
/// </summary>
class TaskModel
{
public int TaskID { get; set; }
public DateTime ITime { get; set; }
}
1.查询计划任务时只管有任务就推给线程池,不等待线程池中任务是否完成.(避免有些计划任务耗时比较长,阻塞后面定时任务执行时间)每隔30秒循环一次计划任务.
2.每条计划任务完成后打印相应信息.(也可记录日志)
3.如果查询计划任务记录数较多,可调整相应的循环时间间隔。避免任务插入线程池时间过长阻塞后面定时任务执行时间。
应用:数据推送程序
场景:在我们日常系统中会存在很多接口数据需要实时推送给第三方平台(如:会员信息发生变化推送给微信平台..)。这时我们就需写一些数据推送程序。
模型:检索任务-->插入线程池-->等待线程池任务完成-->提示任务完成
static void MainMethodB()
{
Thread thread = new Thread(QueryTaskB);
thread.IsBackground = true;
thread.Start(); Console.Read();
} static void QueryTaskB()
{
MutipleThreadResetEvent countdown;
TaskModeB model;
while (true)
{
int RandomNumber = new Random().Next(, );
countdown = new MutipleThreadResetEvent(RandomNumber);
for (int i = ; i < RandomNumber; i++)
{
model = new TaskModeB() { TaskId = i, ITime = DateTime.Now, manualResetEvent = countdown };
ThreadPool.QueueUserWorkItem(InvokeThreadMethodB, model);
} //等待所有线程执行完毕
countdown.WaitAll();
Console.WriteLine("线程池任务已完成.完成时间:{0}", DateTime.Now);
Thread.Sleep();
}
} static void InvokeThreadMethodB(object obj)
{
TaskModeB model = (TaskModeB)obj;
Thread.Sleep();
Console.WriteLine("执行任务ID:{0},执行时间:{1},完成时间:{2}", model.TaskId, model.ITime, DateTime.Now); //发送信号量 本线程执行完毕
model.manualResetEvent.SetOne();
} class TaskModeB
{
public int TaskId { set; get; }
public DateTime ITime { set; get; }
public MutipleThreadResetEvent manualResetEvent { set; get; }
} /// <summary>
/// 解决问题:WaitHandle.WaitAll(evetlist)方法最大只能等待64个ManualResetEvent事件
/// </summary>
public class MutipleThreadResetEvent
{
private readonly ManualResetEvent done;
private readonly int total;
private long current; /// <summary>
/// 构造函数
/// </summary>
/// <param name="total">需要等待执行的线程总数</param>
public MutipleThreadResetEvent(int total)
{
this.total = total;
current = total;
done = new ManualResetEvent(false);
} /// <summary>
/// 唤醒一个等待的线程
/// </summary>
public void SetOne()
{
// Interlocked 原子操作类 ,此处将计数器减1
if (Interlocked.Decrement(ref current) == )
{
//当所以等待线程执行完毕时,唤醒等待的线程
done.Set();
}
} /// <summary>
/// 等待所以线程执行完毕
/// </summary>
public void WaitAll()
{
done.WaitOne();
} /// <summary>
/// 释放对象占用的空间
/// </summary>
public void Dispose()
{
((IDisposable)done).Dispose();
}
}
QueryTaskB()在检索任务记录数后会记录任务条数,并实例化对应的ManualResetEvent数组,做为参数传给线程池中线程任务。
最后等待线程池中所有任务执行完成。后续可根据实际需要编写各自业务逻辑。
两个实例的不同点:是否等待线程池中的所有任务完成。
实例1中定时任务对执行的时间要求比较高,到了某个时间点必须执行某个任务。所以不能等待线程池中的任务完成。
缺点:有任务就插入线程池,有些任务可能会执行很久,线程池每隔30秒循环一次,最后会导致线程池中有存在很多耗时很长的任务在线程池中未执行完。当线程池中线程数达到1023(线程池默认最大线程数)后线程池就不会在创建新的线程数去完成新的任务,只能等待当前线程池中线程数得到释放。
实例2中数据推送程序对推送的时间要求相对1中要低一点。接口表中只要检索到数据就推送给第三方平台。一般每次传输数据量不是很多,但很频繁。
缺点:当推送数据量大时,执行任务时间可能会较长。主线程会等待线程池中的所有任务完成。所有每次循环检索任务的时间间隔可能会出现30S+NS现象。
C# 线程--第四线程实例的更多相关文章
- Java多线程(四) 线程池
一个优秀的软件不会随意的创建.销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理 ...
- 第四节:Task的启动的四种方式以及Task、TaskFactory的线程等待和线程延续的解决方案
一. 背景 揭秘: 在前面的章节介绍过,Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然也可以基本业务需要的多线程场景,但它们在多个线程的等待处理方面 ...
- {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器
Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...
- Java多线程(四) —— 线程并发库之Atomic
一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下 ...
- C#中的线程(四)高级话题
C#中的线程(四)高级话题 Keywords:C# 线程Source:http://www.albahari.com/threading/Author: Joe AlbahariTranslato ...
- Java创建线程的四种方式
Java创建线程的四种方式 1.继承Thread类创建线程 定义Thread类的子类,并重写该类的run方法,run()方法的内容就是该线程执行的内容 创建Thread子类的实例,即创建了线程对象. ...
- java多线程(一)创建线程的四种方式
1. 什么是并发与并行 要想学习多线程,必须先理解什么是并发与并行 并行:指两个或多个事件在同一时刻发生(同时发生). 并发:指两个或多个事件在同一个时间段内发生. 2. 什么是进程.线程 进 ...
- Java并发编程 (四) 线程安全性
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.线程安全性-原子性-atomic-1 1.线程安全性 定义: 当某个线程访问某个类时,不管运行时环境 ...
- java创建线程的四种方法
第一种: 通过继承Thread类创建线程 第二种: 通过实现Runnable接口创建线程 这两种早已烂记于心,这里就不作过多的介绍, 主要介绍其源码 Thread类 implements Runna ...
随机推荐
- Java中throws和throw的区别讲解
当然,你需要明白异常在Java中式以一个对象来看待.并且所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,但是一般情况下Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示, ...
- XSS攻击:SOHU视频XSS漏洞导致其用户成为DDOS肉鸡
XSS又叫CSS (Cross Site Script) ,跨站脚本攻击.恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入当中Web里面的html代码会被运行,从而达到恶意攻击用 ...
- Educational Codeforces Round 1 A. Tricky Sum 暴力
A. Tricky Sum Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/598/problem ...
- Codeforces Gym 100286G Giant Screen 水题
Problem G.Giant ScreenTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/con ...
- Cocos2d-x学习笔记(10)(CCMenu菜单)
1.CCMenu创建方式 CCMenu* menu = CCMenu::create(cocos2d::CCMenuItem* item,--)參数为CCMenuItem菜单项的对象可变參数列表 2. ...
- [AngularJS] Isolate State Mutations in Angular Components
Managing state is one of the hardest things to do in any application. Angular 2 tackles this problem ...
- mysql online ddl2
大家知道,互联网业务是典型的OLTP(online transaction process)应用,这种应用访问数据库的特点是大量的短事务高并发运行.因此任何限制高并发的动作都是不可接受的, ...
- PAT 1018
1018. Public Bike Management (30) There is a public bike service in Hangzhou City which provides gre ...
- AngularJS - 定时器 倒计时例子
<body> <div ng-app="myApp"> <div ng-controller="firstController"& ...
- Helpers\FastCache
Helpers\FastCache phpFastCache is a high-performance, distributed object caching system, generic in ...