c# - 在继续代码之前等待空闲线程槽

标签 c# .net multithreading ssis .net-4.0

完成线程队列的最佳方法是什么,这样我只能拥有最大数量的线程,如果我已经有那么多线程,代码会在继续之前等待空闲插槽。

我的意思的伪代码示例,我相信这可以用更好的方式完成...

(请检查下面的附加要求)

private int _MaxThreads = 10;
private int _CurrentThreads = 0;

public void main(string[] args)
{
    List<object> listWithLotsOfItems = FillWithManyThings();

    while(listWithLotsOfItems.Count> 0)
    {
        // get next item that needs to be worked on
        var item = listWithLotsOfItems[0];
        listWithLotsOfItems.RemoveAt(0);

        // IMPORTANT!, more items can be added as we go.
        listWithLotsOfItems.AddRange(AddMoreItemsToBeProcessed());

        // wait for free thread slot
        while (_CurrentThreads >= _MaxThreads)
            Thread.Sleep(100);

        Interlocked.Increment(ref _CurrentThreads); // risk of letting more than one thread through here...
        Thread t = new Thread(new ParameterizedThreadStart(WorkerThread(item));
        t.Start();
    }
}

public void WorkerThread(object bigheavyObject)
{
    // do heavy work here
    Interlocked.Decrement(ref _CurrentThreads);
}

查看了 Sempahore 但它似乎需要在线程内部运行,而不是在创建之前在线程外部运行。在这个例子中,信号量在线程创建后用于暂停它,在我的例子中,在作业完成之前可能有超过 100k 的线程需要运行,所以我宁愿在插槽可用之前不创建线程. ( link to semaphore example )

在实际应用中,数据可以随着程序的进行添加到项目列表中所以 Parallel.ForEach 也不会真正起作用(我是在 SSIS 包中的脚本组件中执行此操作以将数据发送到非常慢的 WCF)。

SSIS 有 .Net 4.0

最佳答案

所以,首先让我说一下,您尝试做的只是在非常具体的安排中对性能进行小幅提升。在线程分配级别尝试和调整可能需要大量工作,因此请确保在继续之前有充分的理由。

现在,首先,如果你想简单地排队工作,你可以把它放在 .NET 线程池上。它只会分配最大配置的线程,任何不适合这些的工作(如果所有线程都忙)将排队等待直到线程可用。

最简单的方法是调用:

Task.Factory.StartNew(() => { /* Your code */});

这将创建一个 TPL 任务并安排它在默认任务调度程序上运行,该调度程序应依次将任务分配给线程池。

如果您需要等待这些任务完成后再继续,您可以将它们添加到一个集合中,然后使用 Task.WaitAll(...):

var tasks = new List<Task>();

tasks.Add(Task.Factory.StartNew(() => { /* Your code */}));

// Before leaving the script.
Task.WaitAll(tasks);

但是,如果您需要更深入地控制这些任务的调度,您可以考虑创建一个支持有限并发的自定义任务调度程序。 This MSDN article深入了解它的更多细节并提出可能的实现建议,但这不是一项微不足道的任务。

关于c# - 在继续代码之前等待空闲线程槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28413434/

相关文章:

C# 枚举时替换集合

c++ - 在线程之间共享资源(文件,互斥体)

c# - 可访问性不一致 : base class is less accessible than class

c# - 如何确定 MethodInfo 是否是基方法的重写

c# - 使用 C# mvc 添加链接

c# - Pechkin 与 Windows Azure

java - 随着线程数的增加,向 HDD 写入文件变得更慢

c# - 查找在 Visual Studio 或单元测试中未使用 await 的异步用法

.net - 在哪里可以找到 Microsoft .NET Framework 开发指南?

.net - ControlPaint.Light 将橙色更改为洋红色