线程并行化.Net中的同步IO

时间:2010-01-21 03:01:30

标签: .net asynchronous parallel-processing message-queue threadpool

目前,我正在为我的应用程序设计消息传递系统(通过RabbitMQ在后端使用AMQP)。将有多个实例,其中方法可以同时从多个源获取数据(即,不必是顺序查询)。

最初,我打算在方法中为每个不同的请求使用ThreadPool和QueueUserWorkItem,然后以某种方式加入它们。这可能会有问题,因为应用程序的几个不同组件可以同时执行此操作,并且每个组件都可能有大量并行请求会使ThreadPool挨饿。

有更有效/更有效的方法吗?

1 个答案:

答案 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);
}