在我的程序中,只有一定数量的线程才能访问函数。有以下代码:
int totalTasksExecute = 3, currentTasksExecute = 0;
Task[] tasks = new Task[totalTasksExecute];
foreach(ObjModel obj in Objs)
{
if (currentTasksExecute == totalTasksExecute)
{
Task.WaitAll(tasks);
currentTasksExecute = 0;
}
Thread.Sleep(500);
tasks[currentTasksExecute++] = Task.Factory.StartNew(() => GetWebInfo(obj));
}
Task.WaitAll(tasks);
由于它发生了好几次,我决定将它作为一个单独的类发布。在一个类中,我使用 Semaphore 来限制同时访问一个函数。
public class MultiTasks<T>
{
private readonly Action<T> _callback;
private readonly Semaphore semaphore;
private readonly List<T> ts;
private readonly AutoResetEvent[] waitHandles;
private int Count;
public MultiTasks(Action<T> callback, int maxRunTasks, List<T> objListForTask)
{
ts = objListForTask;
_callback = callback;
semaphore = new Semaphore(maxRunTasks, maxRunTasks);
waitHandles = new AutoResetEvent[objListForTask.Count];
for (int i = 0; i < waitHandles.Length; i++)
waitHandles[i] = new AutoResetEvent(false);
}
public void Start(int waitMilliSeconds)
{
Count = 0;
foreach(T obj in ts)
Task.Factory.StartNew(() =>
{
semaphore.WaitOne();
_callback(obj);
waitHandles[Count].Set();
Interlocked.Increment(ref Count);
Thread.Sleep(waitMilliSeconds);
semaphore.Release();
});
WaitHandle.WaitAll(waitHandles);
}
}
我这样称呼:
MultiTasks<ObjModel> multiTasks =
new MultiTasks<ObjModel>(GetWebInfo, 3, objs.ToList());
multiTasks.Start(500);
问题是,在第一种情况下,处理时间大约需要 30 秒,在第二种情况下要长 2 倍。也许这个类没有正确实现?或者我没有正确使用信号量?
如果您正在做一些应该并行运行的事情,但同时不超过 N 个线程,那么使用现成的设计是否有意义?举个例子:
输出将类似于
也就是说,不超过 3 个同时运行的线程。