dotNet中的多线程

基本原理来自这篇msdn上的文章:
http://msdn.microsoft.com/en-us/library/ee789351.aspx

具体步骤如下:

  1. 新建一个类LimitedConcurrencyLevelTaskScheduler

 

  1. /// <summary>
  2. /// Provides a task scheduler that ensures a maximum concurrency level while
  3. /// running on top of the ThreadPool.
  4. /// </summary>
  5. public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
  6. {
  7. /// <summary>Whether the current thread is processing work items.</summary>
  8. [ThreadStatic]
  9. private static bool _currentThreadIsProcessingItems;
  10. /// <summary>The list of tasks to be executed.</summary>
  11. private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
  12. /// <summary>The maximum concurrency level allowed by this scheduler.</summary>
  13. private readonly int _maxDegreeOfParallelism;
  14. /// <summary>Whether the scheduler is currently processing work items.</summary>
  15. private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks)
  16.  
  17. /// <summary>
  18. /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
  19. /// specified degree of parallelism.
  20. /// </summary>
  21. /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
  22. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
  23. {
  24. if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
  25. _maxDegreeOfParallelism = maxDegreeOfParallelism;
  26. }
  27.  
  28. /// <summary>Queues a task to the scheduler.</summary>
  29. /// <param name="task">The task to be queued.</param>
  30. protected sealed override void QueueTask(Task task)
  31. {
  32. // Add the task to the list of tasks to be processed. If there aren't enough
  33. // delegates currently queued or running to process tasks, schedule another.
  34. lock (_tasks)
  35. {
  36. _tasks.AddLast(task);
  37. if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
  38. {
  39. ++_delegatesQueuedOrRunning;
  40. NotifyThreadPoolOfPendingWork();
  41. }
  42. }
  43. }
  44.  
  45. /// <summary>
  46. /// Informs the ThreadPool that there's work to be executed for this scheduler.
  47. /// </summary>
  48. private void NotifyThreadPoolOfPendingWork()
  49. {
  50. ThreadPool.UnsafeQueueUserWorkItem(_ =>
  51. {
  52. // Note that the current thread is now processing work items.
  53. // This is necessary to enable inlining of tasks into this thread.
  54. _currentThreadIsProcessingItems = true;
  55. try
  56. {
  57. // Process all available items in the queue.
  58. while (true)
  59. {
  60. Task item;
  61. lock (_tasks)
  62. {
  63. // When there are no more items to be processed,
  64. // note that we're done processing, and get out.
  65. if (_tasks.Count == 0)
  66. {
  67. --_delegatesQueuedOrRunning;
  68. break;
  69. }
  70.  
  71. // Get the next item from the queue
  72. item = _tasks.First.Value;
  73. _tasks.RemoveFirst();
  74. }
  75.  
  76. // Execute the task we pulled out of the queue
  77. base.TryExecuteTask(item);
  78. }
  79. }
  80. // We're done processing items on the current thread
  81. finally { _currentThreadIsProcessingItems = false; }
  82. }, null);
  83. }
  84.  
  85. /// <summary>Attempts to execute the specified task on the current thread.</summary>
  86. /// <param name="task">The task to be executed.</param>
  87. /// <param name="taskWasPreviouslyQueued"></param>
  88. /// <returns>Whether the task could be executed on the current thread.</returns>
  89. protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
  90. {
  91. // If this thread isn't already processing a task, we don't support inlining
  92. if (!_currentThreadIsProcessingItems) return false;
  93.  
  94. // If the task was previously queued, remove it from the queue
  95. if (taskWasPreviouslyQueued) TryDequeue(task);
  96.  
  97. // Try to run the task.
  98. return base.TryExecuteTask(task);
  99. }
  100.  
  101. /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
  102. /// <param name="task">The task to be removed.</param>
  103. /// <returns>Whether the task could be found and removed.</returns>
  104. protected sealed override bool TryDequeue(Task task)
  105. {
  106. lock (_tasks) return _tasks.Remove(task);
  107. }
  108.  
  109. /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
  110. public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
  111.  
  112. /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
  113. /// <returns>An enumerable of the tasks currently scheduled.</returns>
  114. protected sealed override IEnumerable<Task> GetScheduledTasks()
  115. {
  116. bool lockTaken = false;
  117. try
  118. {
  119. Monitor.TryEnter(_tasks, ref lockTaken);
  120. if (lockTaken) return _tasks.ToArray();
  121. else throw new NotSupportedException();
  122. }
  123. finally
  124. {
  125. if (lockTaken) Monitor.Exit(_tasks);
  126. }
  127. }
  128. }
  129. }

2.初始化TaskScheduler并指定线程数,初始化TaskFactory

            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(1);

            TaskFactory factory = new TaskFactory(lcts);

 

3.用如下的方法启动新线程:

            factory.StartNew(()=> 

                {


										for (int i = 0; i < 500; i++) 

                    {

                        Console.Write("{0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId);

                    }

                }

            );

4.还可以等待所有线程结束后做一些操作:

lcts.Wait();

Console.WriteLine("Execute success!");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值