C#BlockingCollection生成者使用者而不阻塞使用者线程

C#BlockingCollection生成者使用者而不阻塞使用者线程,第1张

概述我有一种情况,我需要有大量(数百)队列,其中的项目应按顺序处理(需要单线程消费者).我的第一个实现, based on the samples,我使用了一个长时间运行的Task per BlockingCollection来使用队列项.但是,我最终得到了一个拥有数百个线程的应用程序,这些线程大部分都处于空闲状态,除了占用内存之外什么都不做 我认为只有在队列中有东西需要处理才能运行消费者任务会更好, 我有一种情况,我需要有大量(数百)队列,其中的项目应按顺序处理(需要单线程消费者).我的第一个实现,based on the samples,我使用了一个长时间运行的Task per BlockingCollection来使用队列项.但是,我最终得到了一个拥有数百个线程的应用程序,这些线程大部分都处于空闲状态,除了占用内存之外什么都不做

我认为只有在队列中有东西需要处理才能运行消费者任务会更好,但是,我无法找到能够提供最佳实践的样本.

我提出了类似于下面的解决方案.但问题是,每个项目都会产生一个新任务(这可能是效率低下的?浪费资源?).但是如果我没有为每个项目创建一个新任务,我不能保证一个项目不会在未处理的队列中.

private object _processSyncObj = new object();    private volatile bool _isProcessing;    private BlockingCollection<string> _queue = new BlockingCollection<string>();    private voID EnqueueItem(string item)    {        _queue.Add(item);        Task.Factory.StartNew(ProcessQueue);    }    private voID ProcessQueue()    {        if (_isProcessing)            return;        lock (_processSyncObj)        {             string item;             while (_isProcessing = _queue.TryTake(out item))             {                 // process item             }        }    }

针对这种情况的最佳实践/最佳解决方案是什么,并保证项目在队列中没有任何情况,但没有消费者在运行?

解决方法 我认为你所做的是合情合理的,因为Task还可以很好地扩展到数百万个任务,针对ThreadPool产生内部子队列,避免过多的上下文切换.

Behind the scenes,tasks are queued to the ThreadPool,which has been enhanced with algorithms that determine and adjust to the number of threads and that provIDe load balancing to maximize throughput. This makes tasks relatively lightweight,and you can create many of them to enable fine-grained parallelism.

Task Parallelism (Task Parallel Library)

…但是你所做的,最终将只是一个正常的任务编程,因为对于每个入队你开始一个任务,所以阻塞集合是非常未使用的.据了解,您关注的是关于触发任务并让TaskScheduler在他们到达时按顺序运行作业.

你知道你也可以自定义TaskScheduler吗?

如何使用Task编程模式,以及自定义TaskScheduler来控制计划任务的流程呢?

例如,您可以创建一个OrderedTaskScheduler,它派生自一个行为如此的limitedConcurrencyLevelTask​​Scheduler ……

The limitedConcurrencyLevelTaskScheduler class offers a task scheduler that ensures a maximum concurrency level while running on top of the ThreadPool. It is necessary to set the maximum degree of parallelism desired for this scheduler.

The OrderedTaskScheduler class provIDes a task scheduler that ensures only one task is executing at a time. Tasks execute in the order that they were queued (FIFO). It is a subclass of limitedConcurrencyLevelTaskScheduler that sends 1 as a parameter for its base class constructor.

您可以找到已经开发的这些调度程序,它们被称为ParallelExtensionsExtras,您可以从here下载它,并从blog post和others阅读一些有关它的文章.

您也可以直接在nuget找到它,并在github找到代码镜像.

请享用! 总结

以上是内存溢出为你收集整理的C#BlockingCollection生成者使用者而不阻塞使用者线程全部内容,希望文章能够帮你解决C#BlockingCollection生成者使用者而不阻塞使用者线程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1216146.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存