Подтвердить что ты не робот

Разница между ThreadPool.QueueUserWorkItem и Parallel.ForEach?

В чем основное отличие двух следующих подходов:

ThreadPool.QueueUserWorkItem

    Clients objClient = new Clients();
    List<Clients> objClientList = Clients.GetClientList();

    foreach (var list in objClientList)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(SendFilesToClient), list);
    } 

System.Threading.Tasks.Parallel ForEach

    Clients objClient = new Clients();
    List<Clients> objClientList = Clients.GetClientList();

    Parallel.ForEach<Clients>(objClientList, list =>
    {
        SendFilesToClient(list);
    });

Я новичок в многопоточности и хочу знать, что произойдет в каждом случае (с точки зрения процесса выполнения), какой уровень многопоточности для каждого подхода? Помогите мне визуализировать оба процесса.

SendFilesToClient: Получает данные из базы данных, конвертирует в Excel и отправляет файл Excel соответствующему клиенту.

Спасибо!

4b9b3361

Ответ 1

Основное различие является функциональным. Parallel.ForEach будет блокировать (по дизайну), поэтому он не вернется, пока все объекты не будут обработаны. Ваша работа с потоком нити thread foreach будет толкать работу на потоки фона, а не блокировать.

Кроме того, версия Parallel.ForEach будет иметь еще одно важное преимущество - необработанные исключения будут отброшены на сайт вызова здесь, а не оставлены необработанными в потоке ThreadPool.

В общем случае Parallel.ForEach будет более эффективным. Оба варианта используют ThreadPool, но Parallel.ForEach выполняет интеллектуальное разбиение на разделы, чтобы предотвратить чрезмерное воспроизведение и уменьшить количество накладных расходов, требуемых планировщиком. Индивидуальные задачи (которые будут отображаться в потоках ThreadPool) будут повторно использоваться и эффективно "объединены", чтобы снизить накладные расходы, особенно если SendFilesToClient - это быстрая операция (которая в этом случае не будет правдой).

Обратите внимание, что вы также можете в качестве третьего варианта использовать PLINQ:

objClientList.AsParallel().ForAll(SendFilesToClient);

Это будет очень похоже на метод Parallel.ForEach с точки зрения производительности и функциональности.