TPL与多线程

dot*_*per 1 c# multithreading task-parallel-library

我是线程新手,我需要澄清以下情况.

我正在研究苹果推送通知服务.我的应用程序要求在向网站添加新交易时向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++;
    }
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

Dav*_*aab 5

从技术上讲,确定可以拆分列表,然后启动并行运行List的线程.您也可以像以前一样自己实现所有内容,但这不是一个好方法.首先将List拆分为并行处理的块已经是什么Parallel.For或者Parallel.ForEach做了什么.没有必要自己重新实现一切.

现在,您不断询问是否可以并行运行300或500个通知.但实际上这不是一个好问题,因为你完全错过了并行运行的重点.

那么,让我解释一下为什么这个问题不好.首先,你应该问自己为什么要并行运行?答案是,您希望通过使用多个CPU核心来运行更快的东西.

现在你的简单想法可能是产生300或500个线程的速度更快,因为你有更多的线程并且它"并行"运行更多的东西.但事实并非如此.

首先,创建一个线程不是"免费"的.您创建的每个线程都有一些开销,创建一个线程需要一些CPU时间,而且还需要一些内存.最重要的是,如果你创建300个线程,它并不意味着并行运行300个线程.如果你有一个8核CPU,那么只有8个线程可以并行运行.创建更多线程甚至可能会损害您的性能.因为现在你的程序需要在线程之间切换constanlty,这也会降低CPU性能.

结果就是这样.如果你有轻量级的一些小代码,它们不会进行大量计算,那么它会导致创建大量线程会降低应用程序速度而不是更快地运行,因为管理线程会产生比运行它更多的开销(对于例子)8个cpu核心.

这意味着,如果你有一个30,000的列表.它通常会以更快的速度将您的列表拆分为8个块,并在8个线程中通过列表来创建300个线程.

你的目标永远不应该是:它能并行运行xxx吗?问题应该是:我需要多少个线程,以及每个线程处理多少项目以使我的工作最快完成.

这是一个重要的区别,因为只是产生更多线程并不意味着某些东西最终会快速发展.

那么你需要多少线程,每个线程应该处理多少项?好吧,你可以编写很多代码来测试它.但是数量从硬件变为硬件.只有4个内核的PC比具有8个内核的系统具有另一个优化.如果你正在做的是IO绑定(例如读/写到磁盘/网络),你也不会通过增加线程来获得更快的速度.

所以你现在可以做的就是测试一切,尝试获得正确的线程数,并进行大量的基准测试以找到最佳数字.

但实际上,这就是TPL库与Task<T>该类的完整目的.该Task<T>班已经看你的电脑有多少CPU的内核有.当您运行任务时,它会自动尝试创建所需的线程,以最大限度地利用您的系统.

所以我的建议是你应该在Task<T>课堂上使用TPL库.在我看来,你不应该自己直接创建线程或自己做分区,因为所有这些都已在TPL中完成.