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版本。