这就是您在 .net 3.5 中使用基类库的方式:对 SetMinThreads 的调用是可选的 - 看看有没有它会发生什么。
您应该在替换为 DoSomethingThatsSlow 时处理超时
public class ThrottledParallelRunnerTest
{
public static void Main()
{
//since the process is just starting up, we need to boost this
ThreadPool.SetMinThreads(10, 10);
IEnumerable<string> args = from i in Enumerable.Range(1, 100)
select "task #" + i;
ThrottledParallelRun(DoSomethingThatsSlow, args, 8);
}
public static void DoSomethingThatsSlow(string urlOrWhatever)
{
Console.Out.WriteLine("{1}: began {0}", urlOrWhatever, DateTime.Now.Ticks);
Thread.Sleep(500);
Console.Out.WriteLine("{1}: ended {0}", urlOrWhatever, DateTime.Now.Ticks);
}
private static void ThrottledParallelRun<T>(Action<T> action, IEnumerable<T> args, int maxThreads)
{
//this thing looks after the throttling
Semaphore semaphore = new Semaphore(maxThreads, maxThreads);
//wrap the action in a try/finally that releases the semaphore
Action<T> releasingAction = a =>
{
try
{
action(a);
}
finally
{
semaphore.Release();
}
};
//store all the IAsyncResult - will help prevent method from returning before completion
List<IAsyncResult> results = new List<IAsyncResult>();
foreach (T a in args)
{
semaphore.WaitOne();
results.Add(releasingAction.BeginInvoke(a, null, null));
}
//now let's make sure everything's returned. Maybe collate exceptions here?
foreach (IAsyncResult result in results)
{
releasingAction.EndInvoke(result);
}
}
}