我是线程的新手,我需要澄清一下下面的场景。
我正在开发苹果推送通知服务。我的应用程序要求在向网站添加新交易时向30k用户发送通知。
我是否可以将30k个用户拆分成列表,每个列表包含1000个用户,并启动多个线程,或者可以使用任务?
下面的方法有效吗?
if (lstDevice.Count > 0)
{
    for (int i = 0; i < lstDevice.Count; i += 2)
    {
        splitList.Add(lstDevice.Skip(i).Take(2).ToList<DeviceHelper>());
    }
    var tasks = new Task[splitList.Count];
    int count=0;
    foreach (List<DeviceHelper> lst in splitList)
    {
        tasks[count] = Task.Factory.StartNew(() =>
        {
            QueueNotifications(lst, pMessage, pSubject, pNotificationType, push);
        },
            TaskCreationOptions.None);
       count++;
    }QueueNotification方法将遍历每个列表项并创建有效负载,如下所示
foreach (DeviceHelper device in splitList)
{
    if (device.PlatformType.ToLower() == "ios")
    {
        push.QueueNotification(new AppleNotification()
                                    .ForDeviceToken(device.DeviceToken)
                                    .WithAlert(pMessage)
                                    .WithBadge(device.Badge)
                                     );
        Console.Write("Waiting for Queue to Finish...");
    }
}
push.StopAllServices(true);发布于 2014-11-03 17:37:06
从技术上讲,可以拆分一个列表,然后启动并行运行列表的线程。您也可以自己实现所有内容,就像您已经做过的那样,但这不是一个好方法。首先,将列表拆分成并行处理的块已经是Parallel.For或Parallel.ForEach所做的事情。没有必要自己重新实现所有的东西。
现在,您经常问是否可以并行运行300或500个通知。但实际上,这不是一个好问题,因为你完全忽略了并行运行某些东西的要点。
那么,让我来解释一下为什么这个问题不好。首先,你应该问问你自己,为什么你想并行运行一些东西?这个问题的答案是,您希望通过使用多个CPU核心来使某些程序运行得更快。
现在你的简单想法可能是,派生300或500个线程更快,因为你有更多的线程,它“并行”运行更多的事情。但事实并非如此。
首先,创建线程并不是“免费的”。您创建的每个线程都有一些开销,创建线程需要一些CPU时间,还需要一些内存。最重要的是,如果你创建了300个线程,并不意味着300个线程并行运行。例如,如果你有一个8核的CPU,那么实际上只有8个线程可以并行运行。创建更多的线程甚至会影响你的性能。因为现在你的程序需要在线程之间切换常量,这也会降低CPU的性能。
这一切的结果就是。如果你有一些轻量级的小代码,不做大量的计算,那么创建大量线程会减慢应用程序的运行速度,而不是更快,因为管理线程比在(例如)8个cpu核心上运行它产生更多的开销。
也就是说,如果你有一份30,000份清单。通常情况下,将列表分成8个块,然后在8个线程中创建300个线程来处理列表会更快。
你的目标永远不应该是:它能并行运行xxx程序吗?问题应该是这样的:我需要多少个线程,每个线程应该处理多少项目才能最快地完成我的工作。
这是一个重要的区别,因为仅仅产生更多的线程并不意味着某些东西最终会很快出现。
那么你需要多少个线程,每个线程应该处理多少个项目呢?你可以写很多代码来测试它。但不同硬件的数量会有所不同。一台只有4个核心的PC比一个有8个核心的系统有另一个最佳选择。如果您正在做的事情是IO受限的(例如,对磁盘/网络的读/写),那么您也不能通过增加线程来获得更快的速度。
因此,您现在可以做的是测试所有内容,尝试获得正确的线程数量,并进行大量基准测试以找到最佳数量。
但实际上,这就是带有Task<T>类的第三方程序库的全部目的。Task<T>类已经查看您的计算机有多少个cpu-core。当你运行你的任务时,它会自动尝试创建尽可能多的线程,以最大限度地利用你的系统。
所以我的建议是,您应该将TPL库与Task<T>类一起使用。在我看来,您永远不应该自己直接创建线程或自己进行分区,因为所有这些都已经在TPL中完成了。
发布于 2014-11-03 16:42:36
我认为Task-Class对你的目标来说是一个很好的选择,因为你可以很容易地处理异步进程,而不需要直接处理线程。
也许这能帮上忙:Task vs Thread differences
但是为了给你一个更好的答案,你应该改进你的问题,给我们更多的细节。
在创建大量并行线程时要小心,因为这会减慢应用程序的运行速度。请阅读来自SO:How many threads is too many?的这篇不错的文章。最好的做法是让它可配置,然后测试一些值。
发布于 2014-11-03 17:01:14
我同意Task是一个很好的选择,但是创建太多的任务也会给你的系统带来风险,对于失败,你的决定也是提出解决方案的一个因素。对我来说,我更喜欢将MSQueue与线程池相结合。
https://stackoverflow.com/questions/26710487
复制相似问题