答案 0 :(得分:5)
答案 1 :(得分:4)
更好的解决方案是使用Semaphore
来限制对资源 1 的并发访问。在您的情况下,资源只是一个处理工作项的代码块。
var finished = new CountdownEvent(1); // Used to wait for the completion of all work items.
var throttle = new Semaphore(3, 3); // Used to throttle the processing of work items.
foreach (WorkItem item in workitems)
{
finished.AddCount();
WorkItem capture = item; // Needed to safely capture the loop variable.
ThreadPool.QueueUserWorkItem(
(state) =>
{
throttle.WaitOne();
try
{
ProcessWorkItem(capture);
}
finally
{
throttle.Release();
finished.Signal();
}
}, null);
}
finished.Signal();
finished.Wait();
在上面的代码中,WorkItem
是一个假设的类,它封装了处理任务所需的特定参数。
Task Parallel Library使这种模式变得更加容易。只需使用Parallel.ForEach
方法并指定一个限制并发的ParallelOptions.MaxDegreesOfParallelism
。
var options = new ParallelOptions();
options.MaxDegreeOfParallelism = 3;
Parallel.ForEach(workitems, options,
(item) =>
{
ProcessWorkItem(item);
});
1 我应该指出,我不喜欢使用ThreadPool
或任何阻止设备阻止Semaphore
个线程。它基本上浪费了线程。您可能想要完全重新考虑您的设计。
答案 2 :(得分:2)
您应该使用Semaphore对象来限制并发线程。
答案 3 :(得分:1)
你说这些文件是开放的:他们实际上是在积极处理,还是刚刚开放? 如果你要把它们打开:去那里,做到了!依赖于连接和资源(在我的情况下是一个数据库连接)在范围结束时关闭应该可以工作,但是可以采取配置/垃圾收集。