目前,我正在为我的应用程序设计消息传递系统(通过RabbitMQ在后端使用AMQP)。将有多个实例,其中方法可以同时从多个源获取数据(即,不必是顺序查询)。
最初,我打算在方法中为每个不同的请求使用ThreadPool和QueueUserWorkItem,然后以某种方式加入它们。这可能会有问题,因为应用程序的几个不同组件可以同时执行此操作,并且每个组件都可能有大量并行请求会使ThreadPool挨饿。
有更有效/更有效的方法吗?
答案 0 :(得分:2)
强调线程池是可以的。你可以抛出一堆工作项 - 数百,数千 - 然后让我们扯掉。不确定你的意思是“饿死”。除非有一组工作项应该以不同的方式进行优先排序,否则您可能不需要担心饥饿。
如果您使用QUWI,则由您决定如何将并行化结果合并回一个结果。
听起来像你在做地图/减少方法。这是一个使用QUWI的快速地图功能,以及如何使用它的示例。
public static IEnumerable<T2> Map_QUWI<T, T2>(List<T> inputs, Func<T, T2> fn)
{
int c = inputs.Count;
if (c == 0) return null;
T2[] result = new T2[c];
if (c == 1)
{
// only one input - perform the work on main thread
result[0] = fn(inputs[0]);
return result;
}
using (ManualResetEvent done = new ManualResetEvent(false))
{
int countdown = inputs.Count;
WaitCallback cb = delegate (Object obj)
{
int ix = (int)obj;
result[ix] = fn(inputs[ix]);
if (Interlocked.Decrement(ref countdown) == 0)
done.Set(); // signal all done
};
// queue up all workitems
for (int i = 0; i < c; i++)
ThreadPool.QueueUserWorkItem(cb,i);
// Wait for done.Set(), which happens in the WaitCallback
// when the last workitem is completed.
done.WaitOne();
}
return result;
}
使用示例:
// returns the number of prime numbers, less than or equal to x
private int NumberOfPrimesLessThanOrEqualTo(int x)
{
int count= 0;
int n = x;
if (n>=2) count++;
if (x%2==0) n--;
if (n>0)
{
do
{
if (IsPrime(n)) count++;
n-=2;
} while (n>0);
}
return count;
}
private void Demo()
{
var list = new List<int>(new int[] {2,4,8,16,32,64,128,256,512,1024,2048,
4096,8192,16384,32768,65536,131072});
Func<int,int> fn = NumberOfPrimesLessThanOrEqualTo;
var result= Map_QUWI(list, fn);
(new List<int>(result)).ForEach(System.Console.WriteLine);
}