C# System.Threading.ReaderWriterLockSlim
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic; public class SynchronizedCache
{
private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
private Dictionary<int, string> innerCache = new Dictionary<int, string>(); public int Count
{ get { return innerCache.Count; } } public string Read(int key)
{
cacheLock.EnterReadLock();
try
{
return innerCache[key];
}
finally
{
cacheLock.ExitReadLock();
}
} public void Add(int key, string value)
{
cacheLock.EnterWriteLock();
try
{
innerCache.Add(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
} public bool AddWithTimeout(int key, string value, int timeout)
{
if (cacheLock.TryEnterWriteLock(timeout))
{
try
{
innerCache.Add(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
return true;
}
else
{
return false;
}
} public AddOrUpdateStatus AddOrUpdate(int key, string value)
{
cacheLock.EnterUpgradeableReadLock();
try
{
string result = null;
if (innerCache.TryGetValue(key, out result))
{
if (result == value)
{
return AddOrUpdateStatus.Unchanged;
}
else
{
cacheLock.EnterWriteLock();
try
{
innerCache[key] = value;
}
finally
{
cacheLock.ExitWriteLock();
}
return AddOrUpdateStatus.Updated;
}
}
else
{
cacheLock.EnterWriteLock();
try
{
innerCache.Add(key, value);
}
finally
{
cacheLock.ExitWriteLock();
}
return AddOrUpdateStatus.Added;
}
}
finally
{
cacheLock.ExitUpgradeableReadLock();
}
} public void Delete(int key)
{
cacheLock.EnterWriteLock();
try
{
innerCache.Remove(key);
}
finally
{
cacheLock.ExitWriteLock();
}
} public enum AddOrUpdateStatus
{
Added,
Updated,
Unchanged
}; ~SynchronizedCache()
{
if (cacheLock != null) cacheLock.Dispose();
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic; public class Example
{
public static void Main()
{
var sc = new SynchronizedCache();
var tasks = new List<Task>();
int itemsWritten = ; // Execute a writer.
tasks.Add(Task.Run( () => { String[] vegetables = { "broccoli", "cauliflower",
"carrot", "sorrel", "baby turnip",
"beet", "brussel sprout",
"cabbage", "plantain",
"spinach", "grape leaves",
"lime leaves", "corn",
"radish", "cucumber",
"raddichio", "lima beans" };
for (int ctr = ; ctr <= vegetables.Length; ctr++)
sc.Add(ctr, vegetables[ctr - ]); itemsWritten = vegetables.Length;
Console.WriteLine("Task {0} wrote {1} items\n",
Task.CurrentId, itemsWritten);
} ));
// Execute two readers, one to read from first to last and the second from last to first.
for (int ctr = ; ctr <= ; ctr++) {
bool desc = Convert.ToBoolean(ctr);
tasks.Add(Task.Run( () => { int start, last, step;
int items;
do {
String output = String.Empty;
items = sc.Count;
if (! desc) {
start = ;
step = ;
last = items;
}
else {
start = items;
step = -;
last = ;
} for (int index = start; desc ? index >= last : index <= last; index += step)
output += String.Format("[{0}] ", sc.Read(index)); Console.WriteLine("Task {0} read {1} items: {2}\n",
Task.CurrentId, items, output);
} while (items < itemsWritten | itemsWritten == );
} ));
}
// Execute a red/update task.
tasks.Add(Task.Run( () => { Thread.Sleep();
for (int ctr = ; ctr <= sc.Count; ctr++) {
String value = sc.Read(ctr);
if (value == "cucumber")
if (sc.AddOrUpdate(ctr, "green bean") != SynchronizedCache.AddOrUpdateStatus.Unchanged)
Console.WriteLine("Changed 'cucumber' to 'green bean'");
}
} )); // Wait for all three tasks to complete.
Task.WaitAll(tasks.ToArray()); // Display the final contents of the cache.
Console.WriteLine();
Console.WriteLine("Values in synchronized cache: ");
for (int ctr = ; ctr <= sc.Count; ctr++)
Console.WriteLine(" {0}: {1}", ctr, sc.Read(ctr)); }
}
// The example displays the following output:
// Task 1 read 0 items:
//
// Task 3 wrote 17 items
//
//
// Task 1 read 17 items: [broccoli] [cauliflower] [carrot] [sorrel] [baby turnip] [
// beet] [brussel sprout] [cabbage] [plantain] [spinach] [grape leaves] [lime leave
// s] [corn] [radish] [cucumber] [raddichio] [lima beans]
//
// Task 2 read 0 items:
//
// Task 2 read 17 items: [lima beans] [raddichio] [cucumber] [radish] [corn] [lime
// leaves] [grape leaves] [spinach] [plantain] [cabbage] [brussel sprout] [beet] [b
// aby turnip] [sorrel] [carrot] [cauliflower] [broccoli]
//
// Changed 'cucumber' to 'green bean'
//
// Values in synchronized cache:
// 1: broccoli
// 2: cauliflower
// 3: carrot
// 4: sorrel
// 5: baby turnip
// 6: beet
// 7: brussel sprout
// 8: cabbage
// 9: plantain
// 10: spinach
// 11: grape leaves
// 12: lime leaves
// 13: corn
// 14: radish
// 15: green bean
// 16: raddichio
// 17: lima beans
构造函数
| ReaderWriterLockSlim() |
使用默认属性值初始化 ReaderWriterLockSlim 类的新实例。 |
| ReaderWriterLockSlim(LockRecursionPolicy) |
在指定锁定递归策略的情况下初始化 ReaderWriterLockSlim 类的新实例。 |
属性
| CurrentReadCount |
获取已进入读取模式锁定状态的独有线程的总数。 |
| IsReadLockHeld |
获取一个值,该值指示当前线程是否已进入读取模式的锁定状态。 |
| IsUpgradeableReadLockHeld |
获取一个值,该值指示当前线程是否已进入可升级模式的锁定状态。 |
| IsWriteLockHeld |
获取一个值,该值指示当前线程是否已进入写入模式的锁定状态。 |
| RecursionPolicy |
获取一个值,该值指示当前 ReaderWriterLockSlim 对象的递归策略。 |
| RecursiveReadCount |
获取当前线程进入读取模式锁定状态的次数,用于指示递归。 |
| RecursiveUpgradeCount |
获取当前线程进入可升级模式锁定状态的次数,用于指示递归。 |
| RecursiveWriteCount |
获取当前线程进入写入模式锁定状态的次数,用于指示递归。 |
| WaitingReadCount |
获取等待进入读取模式锁定状态的线程总数。 |
| WaitingUpgradeCount |
获取等待进入可升级模式锁定状态的线程总数。 |
| WaitingWriteCount |
获取等待进入写入模式锁定状态的线程总数。 |
方法
| Dispose() |
释放 ReaderWriterLockSlim 类的当前实例所使用的所有资源。 |
| EnterReadLock() |
尝试进入读取模式锁定状态。 |
| EnterUpgradeableReadLock() |
尝试进入可升级模式锁定状态。 |
| EnterWriteLock() |
尝试进入写入模式锁定状态。 |
| Equals(Object) |
确定指定的对象是否等于当前对象。 (Inherited from Object) |
| ExitReadLock() |
减少读取模式的递归计数,并在生成的计数为 0(零)时退出读取模式。 |
| ExitUpgradeableReadLock() |
减少可升级模式的递归计数,并在生成的计数为 0(零)时退出可升级模式。 |
| ExitWriteLock() |
减少写入模式的递归计数,并在生成的计数为 0(零)时退出写入模式。 |
| GetHashCode() |
作为默认哈希函数。 (Inherited from Object) |
| GetType() |
获取当前实例的 Type。 (Inherited from Object) |
| MemberwiseClone() |
创建当前 Object 的浅表副本。 (Inherited from Object) |
| ToString() |
返回表示当前对象的字符串。 (Inherited from Object) |
| TryEnterReadLock(Int32) |
尝试进入读取模式锁定状态,可以选择整数超时时间。 |
| TryEnterReadLock(TimeSpan) |
尝试进入读取模式锁定状态,可以选择超时时间。 |
| TryEnterUpgradeableReadLock(Int32) |
尝试进入可升级模式锁定状态,可以选择超时时间。 |
| TryEnterUpgradeableReadLock(TimeSpan) |
尝试进入可升级模式锁定状态,可以选择超时时间。 |
| TryEnterWriteLock(Int32) |
尝试进入写入模式锁定状态,可以选择超时时间。 |
| TryEnterWriteLock(TimeSpan) |
尝试进入写入模式锁定状态,可以选择超时时间。 |
C# System.Threading.ReaderWriterLockSlim的更多相关文章
- c# System.Threading.Thread
using System; using System.Threading; // Simple threading scenario: Start a static method running // ...
- .Net多线程编程—System.Threading.Tasks.Parallel
System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...
- System.Threading.Timer 定时器的用法
System.Threading.Timer 是C# 中的一个定时器,可以定时(不断循环)执行一个任务.它是在线程上执行的,具有很好的安全性.为此 .Net Framework 提供了5个重载的构造 ...
- C# System.Threading.Timer 使用方法
public class TimerHelper { System.Threading.Timer timer; public TaskSendMMS tasksendmms { get; set; ...
- C#中的线程四(System.Threading.Thread)
C#中的线程四(System.Threading.Thread) 1.最简单的多线程调用 System.Threading.Thread类构造方法接受一个ThreadStart委托,改委托不带参数,无 ...
- C#错误之 System.Threading.ThreadAbortException:正在中止线程
参考:http://www.cnblogs.com/chendaoyin/archive/2013/06/27/3159211.html 1.开启一个子线程 //开启一个子线程,子线程调用方法 Met ...
- System.Threading.Timer使用心得
System.Threading.Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高. "只要在使用 Timer,就必须保留对它的引用."对于任何托 ...
- “System.Threading.ThreadAbortException”类型的第一次机会异常在 mscorlib.dll 中发
问题原因: Thread.Abort 方法 .NET Framework 4 其他版本 1(共 1)对本文的评价是有帮助 - 评价此主题 在调用此方法的线程上引发 ThreadAbortExce ...
- System.Threading.ThreadAbortException: 正在中止线程。
在 System.Threading.ThreadAbortException 中第一次偶然出现的"mscorlib.dll"类型的异常 "System.Threadin ...
随机推荐
- springMVC源码分析--视图AbstractView和InternalResourceView(二)
上一篇博客springMVC源码分析--视图View(一)中我们介绍了简单介绍了View的结构实现及运行流程,接下来我们介绍一下View的实现类做的处理操作. AbstractView实现了rende ...
- appium自动化测试之元素定位
方法一 使用SDK中附带的uiautomatorviewer来定位 在SDK安装目录下的tools下有个uiautomatorviewer.bat批处理文件点击运行 运行后(注意appium desk ...
- apache tomcat 集群!
公司需要一个内部测试局域网, 要求可以支持3000并发访问!以前也没做过服务器这方面.临时抱佛脚,查看了N多文档,他人经验,布置好之后,又遇到了N多问题,功夫不负有心人.终于还是完成了要求!观他人的布 ...
- 将SublimeText 添加到鼠标右键的方法
- python自动抢票
# -*- coding: utf-8 -*- from splinter.browser import Browser from time import sleep import traceback ...
- hdu 1542
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 题意: 求所给矩形的覆盖面积 题解: 利用扫描线的思想,先将坐标离散化,之后以y轴分成多个矩形求解, ...
- Codeforces Round #392 (Div. 2)-D. Ability To Convert
D - Ability To Convert 题目大意:给你一个数字 n 接下来再输入一个数字 w(<10^60),表示w这个数字是 n 进制的, 并且超过十进制也用数字表示,这样就有多种组合了 ...
- Phone List HDU1671
字典树的包含与不包含关系 #include<bits/stdc++.h> using namespace std; ][]; ]; ; bool insert1( char *word ) ...
- [转]使用python来操作redis用法详解
转自:使用python来操作redis用法详解 class CommRedisBase(): def __init__(self): REDIS_CONF = {} connection_pool = ...
- Linux使用tcpdump命令抓包并使用wireshark分析
Linux使用tcpdump命令抓包并使用wireshark分析 介绍 有时分析客户端和服务器网络交互的问题时,为了查找问题,需要分别在客户端和服务器上抓包,我们的客户端一般是windows上的,抓包 ...