c#多线程同步之EventWaitHandle再次使用
/// <summary>
/// 文件传输器,用来获取全文文件,自动根据全文文件数量,开启一定数量的线程,采用生产者消费模式
/// </summary>
public class FileTranser
{
private static IFileTranser Transer = new RealFileTranser();
// 文件队列
static Queue<FullTextListViewModel> FileTaskQueue = new Queue<FullTextListViewModel>();
// 为保证线程安全,使用一个锁来保护队列的访问
readonly static object locker = new object();
// 通过 autoResetEvent 给工作线程发信号
static EventWaitHandle autoResetEvent = new AutoResetEvent(false);
public static CancellationTokenSource cancel = null; static int MaxThreadCount = ;
static int MinThreadCount = ;
static int PageSize = ; static List<Thread> threads = new List<Thread>();
static bool IsRunning = false;
public static void Start(FullTextListViewModel model, int total)
{
if (cancel != null && cancel.IsCancellationRequested) return;
if (IsRunning == false || threadCount > threads.Count)
{
int startCount = threadCount - threads.Count;
IsRunning = true;
// 任务开始,启动工作线程
for (int i = ; i < startCount; i++)
{
Thread t = new Thread(Work);
t.Name = "f_" + (i + );
t.IsBackground = false;
t.Start();
threads.Add(t);
}
}
lock (locker)
{
FileTaskQueue.Enqueue(model);
}
autoResetEvent.Set();
}
public static void Cancel()
{
IsRunning = false;
threads.Clear();
if (cancel != null)
{
cancel.Cancel();
}
autoResetEvent.Set();
Logger.Log("取消获取全文的线程执行");
}
/// <summary>执行工作</summary>
static void Work()
{
while (true)
{
if (cancel.IsCancellationRequested)
{
Logger.Log("线程已取消,当前线程:" + Thread.CurrentThread.Name);
autoResetEvent.Set();
break;
}
else
{
FullTextListViewModel model = null;
lock (locker)
{
if (FileTaskQueue.Count > )
{
model = FileTaskQueue.Dequeue();
}
}
if (model != null)
{
Logger.Log("全文传输文件已经开始,当前Id:" + model.ClientTaskId + ",当前线程:" + Thread.CurrentThread.Name);
FileTranser.Transer.DoWork(model);
}
else
{
Logger.Log("线程" + Thread.CurrentThread.Name + ",已被阻塞,等待任务");
autoResetEvent.WaitOne();
}
}
}
}
}
这段不到100行的代码,采用的思想是,生产者消费模式,其中应用了AutoResetEvent ,从字面上看,是自动重置事件,它是EventWaitHandle的一个子类。
我们还是先来看看这段代码所要表达的意思。第8行,定义了一个文件传输队列FileTaskQueue,它用来接收生产者生产的实体,即FullTextListViewModel类型的对象。29-35行,开启了若干个线程,40行,给队列加锁,把model放到队列里,紧接着,通过Set方法,释放被阻塞的线程。此时,如果有三个线程,队列里只有1个model,那么三个线程消费一个model,必然有两个线程直接被阻塞了,那个得到model的线程执行完毕后,也被阻塞了,一直到下一个model进队,再次运行Set方法, 它们当中只有一个线程被解除了阻塞,接着干活,其它线程的继续等待。如果有足够多的model进队了,意味着活多了,这三个线程都会忙碌起来,不会阻塞。
autoResetEvent,每次调用set方法时,只有一个线程被释放。这点很关键,否则在设计多线程的程序时,会有意想不到的结果。
c#多线程同步之EventWaitHandle再次使用的更多相关文章
- c#多线程同步之EventWaitHandle使用
有这么一个场景,我需要借助windows剪贴板把数据插入到word域中. 实现步骤: 1.把剪贴板数据保存到变量. 2.使用剪贴板实现我们的业务. 3.把变量里的数据存回剪贴板. 但是结果却令人诧异, ...
- c#多线程同步之EventWaitHandle的应用
最近在研究前辈写的winform代码,其中有一个功能,前辈用了EventWaitHandle.初读代码,有点不理解,慢慢想来,还是可以理解的.这个功能,就是执行某项比较耗时的任务,需要打开旋转图标,等 ...
- C# 中 多线程同步退出方案 CancellationTokenSource
C# 中提供多线程同步退出机制,详参对象: CancellationTokenSource CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用 ...
- Linux多线程同步方式
当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图,当多个线程同时去修改这片内存时,就可能出现偏差,得到与预期不符合的值.为啥需要同步,一件事情逻辑上一定是有序的,即使在并发环境下:而操作 ...
- [一个经典的多线程同步问题]解决方案一:关键段CS
前面提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题. 本文先介绍如何使用关键段,然后再深层次的分析下关键段的实现机制和原理. 关键段CRITICA ...
- Java中使用CountDownLatch进行多线程同步
CountDownLatch介绍 在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法: 1.synchronized关键字进行同步. 2.Lock锁接口及其实现类ReentrantL ...
- 【53】java的多线程同步剖析
synchronized关键字介绍: synchronized锁定的是对象,这个很重要 例子: class Sync { public synchronized void test() { Syste ...
- windows多线程同步--临界区
推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率 ...
- 【转】windows平台多线程同步之Mutex的应用
线程组成: 线程的内核对象,操作系统用来管理该线程的数据结构. 线程堆栈,它用于维护线程在执行代码时需要的所有参数和局部变量. 操作系统为每一个运行线程安排一定的CPU时间 —— 时间片.系统通 ...
随机推荐
- ubuntu下安装memcached与php扩展测试使用
1,memcached需要libevent,所以要先安装它 下载地址:http://download.chinaunix.net/download.php?id=45065&ResourceI ...
- 微信小程序 sha1 实现密码加密
在utils中的util.js 文件中增加 函数 实现 字符串转换为16进制加密后的字符串 function encodeUTF8(s) { var i, r = [], c, x; for (i = ...
- 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...
- Eclipse (eclipse-jee-luna-SR2-win32)4.4.2 , jdk1.7, pydev 4.5.5版本的 完成的python环境集成
说明: 下面的搭建python2.x环境需要的条件: jdk1.7 eclipse(版本小于4.5) pydev(版本小于5.0) Eclipse和PyDev搭建完美Python开发环境 Window ...
- 对网站视频资源的管控-禁止通过视频的url访问视频
一般静态文件的下载是不经过PHP的,直接由web服务器发送到客户端.但有时候需要实现文件下载的权限控制等功能,这时候就需要经由PHP程序来做权限验证.简单粗暴的做法是,在PHP程序里边先验证权限,验证 ...
- Shell脚本的颜色样式及属性控制
首先看一下格式 echo -e "\033[字背景颜色:文字颜色m字符串\033[0m" 举例 echo -e "\033[41;36m 字体 \033[0m" ...
- 项目中常用的19条MySQL优化
声明一下:下面的优化方案都是基于 " Mysql-索引-BTree类型 " 的 一.EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划. 下面来个简单 ...
- PAT 1003. Emergency 单源最短路
思路:定义表示到达i的最短路径数量,表示到达i的最短径,表示最短路径到达i的最多人数,表示从i到j的距离, 表示i点的人数.每次从u去更新某个节点v的时候,考虑两种情况: 1.,说明到达v新的最短路径 ...
- 关于longPressGesture做一个长按连加的效果(原创)
关于longPressGesture做一个长按连加的效果 解释一下什么意思呢?就是一个button长按之后其数字的一直累加.朋友们可能看起来很简单,无非就是加一个长按手势(longPressGestu ...
- c#获取文件MD5算法
//获取文件MD5算法 private static string GetMD5FromFile(string fileName) { try { FileStream file = new File ...