PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Code/Source/Teaching.Core/Threading/StaTaskScheduler.cs

https://bitbucket.org/BernhardGlueck/teaching
C# | 74 lines | 63 code | 11 blank | 0 comment | 3 complexity | 58c020701dbf5af77698f2dbaa9310eb MD5 | raw file
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Diagnostics.Contracts;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. namespace Teaching.Core.Threading
  9. {
  10. public sealed class StaTaskScheduler : TaskScheduler, IDisposable
  11. {
  12. private BlockingCollection<Task> tasks = new BlockingCollection<Task>();
  13. private readonly List<Thread> threads;
  14. public override int MaximumConcurrencyLevel
  15. {
  16. get { return threads.Count; }
  17. }
  18. protected override void QueueTask(Task task)
  19. {
  20. tasks.Add(task);
  21. }
  22. protected override IEnumerable<Task> GetScheduledTasks()
  23. {
  24. return tasks.ToArray();
  25. }
  26. protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
  27. {
  28. return
  29. Thread.CurrentThread.GetApartmentState() == ApartmentState.STA &&
  30. TryExecuteTask(task);
  31. }
  32. public void Dispose()
  33. {
  34. if (tasks != null)
  35. {
  36. tasks.CompleteAdding();
  37. foreach (var thread in threads)
  38. {
  39. thread.Join();
  40. }
  41. tasks.Dispose();
  42. tasks = null;
  43. }
  44. }
  45. public StaTaskScheduler(int numberOfThreads)
  46. {
  47. Contract.Requires<ArgumentOutOfRangeException>(numberOfThreads > 0,"numberOfThreads");
  48. threads = Enumerable.Range(0, numberOfThreads).Select(i =>
  49. {
  50. var thread = new Thread(() =>
  51. {
  52. foreach (var t in tasks.GetConsumingEnumerable())
  53. {
  54. TryExecuteTask(t);
  55. }
  56. }) {IsBackground = true};
  57. thread.SetApartmentState(ApartmentState.STA);
  58. return thread;
  59. }).ToList();
  60. threads.ForEach(t => t.Start());
  61. }
  62. }
  63. }