PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Code/Source/Teaching.Threading.Cli/Synchronization/SemaphoreSlim.cs

https://bitbucket.org/BernhardGlueck/teaching
C# | 98 lines | 84 code | 14 blank | 0 comment | 2 complexity | 5512f762da94c388659f6d2c070f1544 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Threading;
  6. using Teaching.Core.Cli;
  7. using Teaching.Core.Patterns;
  8. using Teaching.Core.Threading;
  9. namespace Teaching.Threading.Cli.Synchronization
  10. {
  11. public class SemaphoreBoundedQueue<T> : DisposableBase
  12. {
  13. private readonly Queue<T> items = new Queue<T>();
  14. private readonly System.Threading.SemaphoreSlim producerSemaphore;
  15. private readonly System.Threading.SemaphoreSlim consumerSemaphore;
  16. private readonly System.Threading.Mutex mutex = new System.Threading.Mutex();
  17. public SemaphoreBoundedQueue(int capacity = 0)
  18. {
  19. capacity = capacity < 1 ? Environment.ProcessorCount : capacity;
  20. consumerSemaphore = new System.Threading.SemaphoreSlim(0,capacity);
  21. producerSemaphore = new System.Threading.SemaphoreSlim(capacity,capacity);
  22. }
  23. public void Enqueue(T item)
  24. {
  25. producerSemaphore.Wait();
  26. mutex.WaitOne();
  27. try
  28. {
  29. items.Enqueue(item);
  30. }
  31. finally
  32. {
  33. mutex.ReleaseMutex();
  34. }
  35. consumerSemaphore.Release();
  36. }
  37. public T Dequeue()
  38. {
  39. consumerSemaphore.Wait();
  40. mutex.WaitOne();
  41. var result = default(T);
  42. try
  43. {
  44. result = items.Dequeue();
  45. }
  46. finally
  47. {
  48. mutex.ReleaseMutex();
  49. }
  50. producerSemaphore.Release();
  51. return result;
  52. }
  53. protected override void OnDispose()
  54. {
  55. producerSemaphore.Dispose();
  56. consumerSemaphore.Dispose();
  57. mutex.Dispose();
  58. }
  59. }
  60. [CliSample("semaphoreslim",15,"SemaphoreSlim usage ( bounded queue)")]
  61. public class SemaphoreSlim : CliSampleBase
  62. {
  63. protected override void OnExecute()
  64. {
  65. using( var queue = new SemaphoreBoundedQueue<string>())
  66. {
  67. var threads = Enumerable.Range(0, Environment.ProcessorCount).Select(i => new DisposableThread(c =>
  68. {
  69. if ( i % 2 == 0 )
  70. {
  71. queue.Enqueue(i.ToString(CultureInfo.InvariantCulture));
  72. Output.WriteLine("Enqueued");
  73. }
  74. else
  75. {
  76. queue.Dequeue();
  77. Output.WriteLine("Dequeued");
  78. }
  79. })).ToArray();
  80. threads.ExecuteAndWait(() => Thread.Sleep(5000));
  81. }
  82. }
  83. }
  84. }