C# 在C中一次执行X个线程的操作列表#

C# 在C中一次执行X个线程的操作列表#,c#,.net,multithreading,C#,.net,Multithreading,假设我有一个 List<Thread> df = new List<Thread>(); // I add 500 instances of delegate() { somemethod(a,b) }; to df List df=new List(); //我添加了500个delegate(){somemethod(a,b)}的实例;到df 现在,我想一次最多运行X个项目来处理所有df项目,我如何才能做到这一点呢?与其查看线程列表,不如查看线程池:。在线程池中,池

假设我有一个

List<Thread> df = new List<Thread>();
// I add 500 instances of delegate() { somemethod(a,b) }; to df
List df=new List();
//我添加了500个delegate(){somemethod(a,b)}的实例;到df

现在,我想一次最多运行X个项目来处理所有df项目,我如何才能做到这一点呢?

与其查看线程列表,不如查看线程池:。在线程池中,池中的线程数是“X个并发项”,您可以使用ThreadPool.QueueUserWorkItem(…);对于每位学员。

请看以下内容:

这是《简而言之》一书中的一章范例。阅读整个章节对您有好处,但您可以关注我提供的链接部分:生产者和消费者队列

具体来说,请阅读以下摘录:

“另一种常见的线程方案是让后台工作进程处理队列中的任务。这称为生产者/消费者队列:生产者将任务排入队列;使用者将工作线程上的任务出列。。。生产者/消费者队列是可伸缩的,因为可以创建多个消费者——每个消费者为同一队列提供服务,但在一个单独的线程上。”


如果您创建生产者/消费者队列,如本章中的示例所示,您可以创建消费者的多个实例。这样,每个消费者将从队列中退出一个代理。

您可以使用多种选项。根据您访问的框架,选项可能会有所不同。您可以通过NET 4,您有:线程类w/Signals、线程池、异步委托调用、任务并行库

我将在这里介绍您的几个选项,您可以选择最适合您需要的选项

线程和信号 第一个选项是最手动的。您可以将Thread类的实例旋转到阈值X,并且每当一个线程完成时,旋转另一个线程

示例

public void ProcessDelegates(IList<Action> thingsToDo, int maxConcurrency)
{
    int currentConcurrency = 0;
    var autoevent = new AutoResetEvent(false);
    foreach (var thingToDo in thingsToDo)
    {
        var thread = new Thread(
            () =>
            {
                thingToDo();
                autoevent.Set();
            }
        );

        if (++currentConcurrency >= maxConcurrency)
        {
            autoevent.WaitOne();
            --currentConcurrency;
        }
    }
}
ThreadPool.QueueUserWorkItem(
    data =>
    {
        thingToDo(a, b);
    }
);
public void ProcessDelegates(IList<Action> thingsToDo, int maxConcurrency)
{
    int currentConcurrency = 0;        
    IList<WaitHandle> resultHandles = new List<WaitHandle>();

    foreach (var thingToDo in thingsToDo)
    {
        var asyncResult = thingToDo.BeginInvoke();
        resultHandles.Add(asyncResult.AsyncWaitHandle);

        if (++currentConcurrency >= maxConcurrency)
        {
            WaitHandle.WaitAny(resultHandles.ToArray());
            --currentConcurrency;
        }
    }
}
public void ProcessDelegates(IList<Action> thingsToDo)
{
    var tasks = thingsToDo.Select(
        ttd => Task.Factory.StartNew(ttd, TaskCreationOptions.PreferFairness)
    ).ToArray();

    Task.WaitAll(tasks);
}
异步委托调用 因为您使用的是委托,所以可以使用异步调用来实现线程。这是一种更抽象的多线程方法,有时更易于管理。在这种情况下,这与手动启动自己的线程非常相似。应该注意的是,Delegate.BeginInvoke在内部使用线程池,而sa适用于使用线程池本身的me规则也适用于此处

示例

public void ProcessDelegates(IList<Action> thingsToDo, int maxConcurrency)
{
    int currentConcurrency = 0;
    var autoevent = new AutoResetEvent(false);
    foreach (var thingToDo in thingsToDo)
    {
        var thread = new Thread(
            () =>
            {
                thingToDo();
                autoevent.Set();
            }
        );

        if (++currentConcurrency >= maxConcurrency)
        {
            autoevent.WaitOne();
            --currentConcurrency;
        }
    }
}
ThreadPool.QueueUserWorkItem(
    data =>
    {
        thingToDo(a, b);
    }
);
public void ProcessDelegates(IList<Action> thingsToDo, int maxConcurrency)
{
    int currentConcurrency = 0;        
    IList<WaitHandle> resultHandles = new List<WaitHandle>();

    foreach (var thingToDo in thingsToDo)
    {
        var asyncResult = thingToDo.BeginInvoke();
        resultHandles.Add(asyncResult.AsyncWaitHandle);

        if (++currentConcurrency >= maxConcurrency)
        {
            WaitHandle.WaitAny(resultHandles.ToArray());
            --currentConcurrency;
        }
    }
}
public void ProcessDelegates(IList<Action> thingsToDo)
{
    var tasks = thingsToDo.Select(
        ttd => Task.Factory.StartNew(ttd, TaskCreationOptions.PreferFairness)
    ).ToArray();

    Task.WaitAll(tasks);
}

免责声明:这些示例都是我想不起的,而且非常简单,因此我无法保证它们在实际场景中的完美稳定性。我建议使用这些示例作为基础,以实现适用于任何应用程序的线程。

对此的答案将非常简单取决于您使用的.net版本。