1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Collections.Concurrent;
5 using System.Linq;
6 using System.Threading;
7 using System.Threading.Tasks;
8
9
10 // Sample implementation of IProducerConsumerCollection(T)
11 // -- in this case, a thread-safe stack.
12 public class SafeStack<T> : IProducerConsumerCollection<T>
13 {
14 // Used for enforcing thread-safety
15 private object m_lockObject = new object();
16
17 // We'll use a regular old Stack for our core operations
18 private Stack<T> m_sequentialStack = null;
19
20 //
21 // Constructors
22 //
23 public SafeStack()
24 {
25 m_sequentialStack = new Stack<T>();
26 }
27
28 public SafeStack(IEnumerable<T> collection)
29 {
30 m_sequentialStack = new Stack<T>(collection);
31 }
32
33 //
34 // Safe Push/Pop support
35 //
36 public void Push(T item)
37 {
38 lock (m_lockObject) m_sequentialStack.Push(item);
39 }
40
41 public bool TryPop(out T item)
42 {
43 bool rval = true;
44 lock (m_lockObject)
45 {
46 if (m_sequentialStack.Count == 0) { item = default(T); rval = false; }
47 else item = m_sequentialStack.Pop();
48 }
49 return rval;
50 }
51
52 //
53 // IProducerConsumerCollection(T) support
54 //
55 public bool TryTake(out T item)
56 {
57 return TryPop(out item);
58 }
59
60 public bool TryAdd(T item)
61 {
62 Push(item);
63 return true; // Push doesn't fail
64 }
65
66 public T[] ToArray()
67 {
68 T[] rval = null;
69 lock (m_lockObject) rval = m_sequentialStack.ToArray();
70 return rval;
71 }
72
73 public void CopyTo(T[] array, int index)
74 {
75 lock (m_lockObject) m_sequentialStack.CopyTo(array, index);
76 }
77
78
79
80 //
81 // Support for IEnumerable(T)
82 //
83 public IEnumerator<T> GetEnumerator()
84 {
85 // The performance here will be unfortunate for large stacks,
86 // but thread-safety is effectively implemented.
87 Stack<T> stackCopy = null;
88 lock (m_lockObject) stackCopy = new Stack<T>(m_sequentialStack);
89 return stackCopy.GetEnumerator();
90 }
91
92
93 //
94 // Support for IEnumerable
95 //
96 IEnumerator IEnumerable.GetEnumerator()
97 {
98 return ((IEnumerable<T>)this).GetEnumerator();
99 }
100
101 //
102 // Support for ICollection
103 //
104 public bool IsSynchronized
105 {
106 get { return true; }
107 }
108
109 public object SyncRoot
110 {
111 get { return m_lockObject; }
112 }
113
114 public int Count
115 {
116 get { return m_sequentialStack.Count; }
117 }
118
119 public void CopyTo(Array array, int index)
120 {
121 lock (m_lockObject) ((ICollection)m_sequentialStack).CopyTo(array, index);
122 }
123 }
124
125 public class Program
126 {
127 static void Main()
128 {
129 TestSafeStack();
130
131 // Keep the console window open in debug mode.
132 Console.WriteLine("Press any key to exit.");
133 Console.ReadKey();
134 }
135
136 // Test our implementation of IProducerConsumerCollection(T)
137 // Demonstrates:
138 // IPCC(T).TryAdd()
139 // IPCC(T).TryTake()
140 // IPCC(T).CopyTo()
141 static void TestSafeStack()
142 {
143 SafeStack<int> stack = new SafeStack<int>();
144 IProducerConsumerCollection<int> ipcc = (IProducerConsumerCollection<int>)stack;
145
146 // Test Push()/TryAdd()
147 stack.Push(10); Console.WriteLine("Pushed 10");
148 ipcc.TryAdd(20); Console.WriteLine("IPCC.TryAdded 20");
149 stack.Push(15); Console.WriteLine("Pushed 15");
150
151 int[] testArray = new int[3];
152
153 // Try CopyTo() within boundaries
154 try
155 {
156 ipcc.CopyTo(testArray, 0);
157 Console.WriteLine("CopyTo() within boundaries worked, as expected");
158 }
159 catch (Exception e)
160 {
161 Console.WriteLine("CopyTo() within boundaries unexpectedly threw an exception: {0}", e.Message);
162 }
163
164 // Try CopyTo() that overflows
165 try
166 {
167 ipcc.CopyTo(testArray, 1);
168 Console.WriteLine("CopyTo() with index overflow worked, and it SHOULD NOT HAVE");
169 }
170 catch (Exception e)
171 {
172 Console.WriteLine("CopyTo() with index overflow threw an exception, as expected: {0}", e.Message);
173 }
174
175 // Test enumeration
176 Console.Write("Enumeration (should be three items): ");
177 foreach (int item in stack) Console.Write("{0} ", item);
178 Console.WriteLine("");
179
180 // Test TryPop()
181 int popped = 0;
182 if (stack.TryPop(out popped))
183 {
184 Console.WriteLine("Successfully popped {0}", popped);
185 }
186 else Console.WriteLine("FAILED to pop!!");
187
188 // Test Count
189 Console.WriteLine("stack count is {0}, should be 2", stack.Count);
190
191 // Test TryTake()
192 if (ipcc.TryTake(out popped))
193 {
194 Console.WriteLine("Successfully IPCC-TryTaked {0}", popped);
195 }
196 else Console.WriteLine("FAILED to IPCC.TryTake!!");
197 }
198 }
199

.NET并行计算和并发11:并发接口 IProducerConsumerCollection的更多相关文章

  1. C++11 并发编程库

    C++11 并发编程 C++11 新标准中引入了几个头文件来支持多线程编程,他们分别是: <atomic>:该头文主要声明了两个类, std::atomic 和 std::atomic_f ...

  2. C++11 并发指南后续更新

    C++11 并发指南的第一篇是 2013 年 8 月 3 号写的,到今天(2013 年 8 月 31 号)差不多一个月了,前前后后共写了 6 章(目前共 8 篇)博客介绍 C++11 的并发编程,但还 ...

  3. C++11 并发指南系列

    本系列文章主要介绍 C++11 并发编程,计划分为 9 章介绍 C++11 的并发和多线程编程,分别如下: C++11 并发指南一(C++11 多线程初探)(本章计划 1-2 篇,已完成 1 篇) C ...

  4. C++11 并发指南三(Lock 详解)

    在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...

  5. C++11 并发指南六(atomic 类型详解四 C 风格原子操作介绍)

    前面三篇文章<C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)>.<C++11 并发指南六( <atomic> 类型详解二 std::at ...

  6. C++11 并发指南六(atomic 类型详解三 std::atomic (续))

    C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...

  7. C++11 并发指南六( <atomic> 类型详解二 std::atomic )

    C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)  一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...

  8. C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)

    C++11 并发指南已经写了 5 章,前五章重点介绍了多线程编程方面的内容,但大部分内容只涉及多线程.互斥量.条件变量和异步编程相关的 API,C++11 程序员完全可以不必知道这些 API 在底层是 ...

  9. C++11 并发指南五(std::condition_variable 详解)

    前面三讲<C++11 并发指南二(std::thread 详解)>,<C++11 并发指南三(std::mutex 详解)>分别介绍了 std::thread,std::mut ...

  10. C++11并发内存模型学习

    C++11标准已发布多年,编译器支持也逐渐完善,例如ms平台上从vc2008 tr1到vc2013.新标准对C++改进体现在三方面:1.语言特性(auto,右值,lambda,foreach):2.标 ...

随机推荐

  1. Pandas Series和DataFrame的基本概念

    1,创建Series 1.1,通过iterable创建Series Series接收参数是Iterable,不能是Iterator pd.Series(Iterable) 可以多加一个index参数, ...

  2. 记一次oracle数据库复制过程

    记录一次自己数据库复制的过程(从公司测试环境复制到客户测试环境),主要是每次自己都会忘记,不如记录一下,方便自己以后找,因此,本篇内容不会很详细,主要是用于给我自己提醒,相对于一种记笔记的效果. cm ...

  3. 解决Git Revert操作后再次Merge代码被冲掉的问题

    转:https://blog.csdn.net/paul_wei2008/article/details/77477932 https://blog.csdn.net/cxn945/article/d ...

  4. Case 条件运算符

    Case运算有两种写法,平常用的都比较多,这里只简单复习下,Case的语法帮助里就好,这里我尝试用颜色区分的方式让大家一眼就能了解其结构: 写法一:) select case when PriceTy ...

  5. 爬虫(三)http和https协议

    一.HTTP协议 1.官方概念: HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文 ...

  6. 从零开始搭建Webpack+react框架

    1.下载node.js Node.js官网下载 , 安装: 安装成功后在控制台输入node -v 可查看当前版本: $ node -v v10.15.0 输入npm -v查看npm版本: $ npm ...

  7. angular2学习笔记3

    一.项目搭建 二.生成首页的4个tab页面 三.运行部署及配置

  8. 【调试基础】Part 1 寄存器

    01 寄存器体系 02 16/32/64位寄存器

  9. Spring Websocket实现简易在线聊天功能

    针对Spring Websocket的实现,我参照了其他博主的文章https://www.cnblogs.com/leechenxiang/p/5306372.html 下面直接给出实现: 一.引入相 ...

  10. Scrapy框架学习第二天

    编写scrapy爬虫的具体流程最初:分析网站页面需要爬取的结构第一步:创建scrapy项目:scrapy startproject +文件名第二步:打开项目第三步:编写items.py第四步:创建爬虫 ...