如何使用Parallel </t>调用Task <t>列表

时间:2013-06-07 17:07:46

标签: c# task-parallel-library async-await class-library

我有一个按特定顺序排列的异步调用列表,无论哪个都是先完成或最后完成。所有这些异步任务都返回位图。所有异步任务都返回一个Bitmap接受,它返回一个Bitmaps List列表。

出于测试目的,我能够更好地处理使用Parallel vs just Task的不同之处我需要有人向我展示如何调用这些async Task中的每一个并设置一个包含所有列表的局部变量返回的异步结果。

  1. 如何并行。执行这些任务
  2. 如何检索每个已完成任务的值,并使用返回的结果设置局部变量。
  3. ---我只是在等待每个任务的代码。

    public async static Task<PdfSharp.Pdf.PdfDocument> RollUpDrawingsPDF(IElevation elevation)
    {
    
        List<Bitmap> allSheets = new List<Bitmap>();
    
        var processedParts = new PartsProcessor.PartProcessor().ProcessParts(elevation);
    
        //elevation
        allSheets.Add(await ShopDrawing.Manager.GetElevationDrawing(elevation, true, RotateFlipType.Rotate90FlipNone));
    
        //door schedules, 3 schedules per sheet
        allSheets.AddRange(await ShopDrawing.Door.GetDoorSecheduleSheets(elevation, RotateFlipType.Rotate90FlipNone, 3));
    
        //materials list
        allSheets.Add(await MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing());
    
        //optimized parts
        allSheets.Add(await Optimization.Manager.GetOptimizedParts(processedParts).GetDrawing());
    
        //cut sheet
        allSheets.Add(await CutSheet.Manager.GetCutSheet(processedParts).GetDrawing());
    
        return await PDFMaker.PDFManager.GetPDF(allSheets, true);
    }
    

    ------ 代码我想在Parallel.ForEach中运行但是这不起作用,而是一个帮助的起点。对于每个返回的任务结果,我需要设置该并行任务结果的allSheets的局部变量。

        public async static Task<PdfSharp.Pdf.PdfDocument> RollUpDrawingsPDF(IElevation elevation)
    {
    
        List<Bitmap> allSheets = new List<Bitmap>();
    
        var processedParts = new PartsProcessor.PartProcessor().ProcessParts(elevation);
    
        Task[] myTask = new Task[5];
        myTask[0] = ShopDrawing.Manager.GetElevationDrawing(elevation, true, RotateFlipType.Rotate90FlipNone);
        myTask[1] = ShopDrawing.Door.GetDoorSecheduleSheets(elevation, RotateFlipType.Rotate90FlipNone, 3);
        myTask[2] = MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing();
        myTask[3] = Optimization.Manager.GetOptimizedParts(processedParts).GetDrawing();
        myTask[4] = CutSheet.Manager.GetCutSheet(processedParts).GetDrawing();
    
    
    
        var x = Parallel.ForEach(myTask, t => t.Wait());
    
        ////elevation
        //allSheets.Add(await );
    
        ////door schedules, 3 schedules per sheet
        //allSheets.AddRange(await);
    
        ////materials list
        //allSheets.Add(await );
    
        ////optimized parts
        //allSheets.Add(await );
    
        ////cut sheet
        //allSheets.Add(await );
    
        return await PDFMaker.PDFManager.GetPDF(allSheets, true);
    }
    

    我如何为这段代码实现Parallel.ForEach?

    * 讨论代码示例。当其他方法返回一个Bitmap *

    时,如何返回List
    async Task<Bitmap[]> RollUpHelper(IElevation elevation, PartsProcessor.ProcessedParts       processedParts)
                {
                    return await Task<Bitmap[]>.WhenAll(
    
     ShopDrawing.Manager.GetElevationDrawing(elevation, true, RotateFlipType.Rotate90FlipNone),
                         //ShopDrawing.Door.GetDoorSecheduleSheets(elevation,RotateFlipType.Rotate90FlipNone, 3),
                         MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing(),
                         MaterialsList.Manager.GetMaterialList(processedParts).GetDrawing(),
                         CutSheet.Manager.GetCutSheet(processedParts).GetDrawing()
                          );
    
                }
    

2 个答案:

答案 0 :(得分:6)

Parallel.ForEach()用于并行运行多个同步操作。

您希望等待一些异步 Task完成:

await Task.WhenAll(tasks);

答案 1 :(得分:0)

扩展SLaks&#39;回答:

Task.WhenAll()会返回由其等待的任务返回的所有结果的数组,因此您无需自行管理。

以下是我在示例中使用string代替Bitmap的示例。请注意其中一名工作人员如何返回List<string>并将其转换为List<string>一项,以使其与其他项目的类型相同。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;

    namespace Demo
    {
        class Data
        {
            public string Value;
            public Data(string value) { Value = value; }
        }

        class Program
        {
            async Task<List<string>[]>  RunAsync()
            {
                return await Task.WhenAll
                (
                    Task.Factory.StartNew(() => 
                        new List<string> {Worker1(new Data("One"))}),

                    Task.Factory.StartNew(() => 
                        Worker2(new Data("Two"))),

                    Task.Factory.StartNew(() => 
                        Worker3(new Data("Three")))
                );

            }

            void Run()
            {
                var results = RunAsync().Result;

                // Now results is an array of List<string>, so we can iterate the results.

                foreach (var result in results)
                {
                    result.Print();
                    Console.WriteLine("--------------");
                }
            }

            string Worker1(Data data)
            {
                Thread.Sleep(1000);
                return data.Value;
            }

            List<string> Worker2(Data data)
            {
                Thread.Sleep(1500);
                return Enumerable.Repeat(data.Value, 2).ToList();
            }

            List<string> Worker3(Data data)
            {
                Thread.Sleep(2000);
                return Enumerable.Repeat(data.Value, 3).ToList();
            }

            static void Main()
            {
                new Program().Run();
            }
        }

        static class DemoUtil
        {
            public static void Print(this object self)
            {
                Console.WriteLine(self);
            }

            public static void Print(this string self)
            {
                Console.WriteLine(self);
            }

            public static void Print<T>(this IEnumerable<T> self)
            {
                foreach (var item in self)
                    Console.WriteLine(item);
            }
        }
    }