/Code/Source/Teaching.Threading.Cli/Synchronization/SemaphoreSlim.cs
C# | 98 lines | 84 code | 14 blank | 0 comment | 2 complexity | 5512f762da94c388659f6d2c070f1544 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Threading;
- using Teaching.Core.Cli;
- using Teaching.Core.Patterns;
- using Teaching.Core.Threading;
-
- namespace Teaching.Threading.Cli.Synchronization
- {
- public class SemaphoreBoundedQueue<T> : DisposableBase
- {
- private readonly Queue<T> items = new Queue<T>();
-
- private readonly System.Threading.SemaphoreSlim producerSemaphore;
- private readonly System.Threading.SemaphoreSlim consumerSemaphore;
- private readonly System.Threading.Mutex mutex = new System.Threading.Mutex();
-
- public SemaphoreBoundedQueue(int capacity = 0)
- {
- capacity = capacity < 1 ? Environment.ProcessorCount : capacity;
- consumerSemaphore = new System.Threading.SemaphoreSlim(0,capacity);
- producerSemaphore = new System.Threading.SemaphoreSlim(capacity,capacity);
- }
-
- public void Enqueue(T item)
- {
- producerSemaphore.Wait();
- mutex.WaitOne();
-
- try
- {
- items.Enqueue(item);
- }
- finally
- {
- mutex.ReleaseMutex();
- }
-
- consumerSemaphore.Release();
- }
-
- public T Dequeue()
- {
- consumerSemaphore.Wait();
- mutex.WaitOne();
-
- var result = default(T);
-
- try
- {
- result = items.Dequeue();
- }
- finally
- {
- mutex.ReleaseMutex();
- }
-
- producerSemaphore.Release();
-
- return result;
- }
-
- protected override void OnDispose()
- {
- producerSemaphore.Dispose();
- consumerSemaphore.Dispose();
- mutex.Dispose();
- }
- }
-
- [CliSample("semaphoreslim",15,"SemaphoreSlim usage ( bounded queue)")]
- public class SemaphoreSlim : CliSampleBase
- {
- protected override void OnExecute()
- {
- using( var queue = new SemaphoreBoundedQueue<string>())
- {
- var threads = Enumerable.Range(0, Environment.ProcessorCount).Select(i => new DisposableThread(c =>
- {
- if ( i % 2 == 0 )
- {
- queue.Enqueue(i.ToString(CultureInfo.InvariantCulture));
- Output.WriteLine("Enqueued");
- }
- else
- {
- queue.Dequeue();
- Output.WriteLine("Dequeued");
- }
- })).ToArray();
-
- threads.ExecuteAndWait(() => Thread.Sleep(5000));
- }
- }
- }
- }